Java笔记(8)多态和对象实例化

Java笔记(8)——多态和对象实例化

文章目录

  • Java笔记(8)——多态和对象实例化
    • this和super的区别
    • 简单类对象的实例化过程
    • 子类对象实例化过程
    • 面向对象特征之三:多态性
      • Java引用变量有两个类型:
      • 多态性(2):
      • 多态类型(3):
      • 虚拟方法调用(Virtual Method Invocation)
    • 多态小节
    • 多态性应用举例
    • instanceof操作符
    • Object类
      • Object类中的主要方法:

this和super的区别

Java笔记(8)多态和对象实例化_第1张图片

在子类中,通过this或者说super调用构造器,只能使用一个,因为都要占据第一行

简单类对象的实例化过程

public class Person{
    
    public Person(){
        Person p =new Person();
    }
    
    int age=1;
    String name="zhangsan";
    int sex=0;
    
    public void showInfo(){
        System.out.println(this.age);
        System.out.println(this.name);
        System.out.prinln(this.sex);
    }
    
    public voif setInfor(int age,String name,int sex){
        this.age=age;
        this.name=name;
        this.sex=sex;
    }
}
Java笔记(8)多态和对象实例化_第2张图片

子类对象实例化过程

Java笔记(8)多态和对象实例化_第3张图片
​ (1)先加载父类,后加载子类

​ (2)本例子中类的属性没有赋值,所有显示初始化就省略了

面向对象特征之三:多态性

多态性——面向对象最重要的概念,在Java里面有两种体现

  1. 方法的重载(overload)和重写(overwrite)。重载体现同名方法不同逻辑,重写体现子类可使用父类相同方法名覆盖父类逻辑,父类想修改逻辑,有别的代码要使用父类方法,,用子类继承父类,重写父类的方法

  2. 对象的多态性 ———可以直接应用在抽象类和接口上。

Java引用变量有两个类型:

(1)编译时类型和运行时类型。编译时类型有声明该变量使用的类型决定,运行时类型由实际赋给该变量的对象决定

(2)若编译时类型和运行时类型不一致,就出现多态(Polymorphism)

多态性(2):

对象的多态——在java中,子类的对象可以代替父类的对象使用

(1)一个变量只能有一种确定的数据类型

(2)一个引用类型变量可能指向(引用)多种不同类型的对象

Person p =new Studnet();
Person e =new Studnet();//Person类型的变量e,指向Student类型的对象

子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象;向上转型(upcasting);把子类的对象可以给父类的类型的变量引用。

多态类型(3):

一个引用类型变量如果声明为父类的类型,但实际引用的是子类的对象,那么该变量就不能再访问子类中添加的属性和方法。

Student m=new Student();
m.school="pku";//合法,Student类有school成员变量
Person e=new Student();
e.school="pku";//非法,Person类没有school成员变量
//属性是在编译时确定的,编译时e为Person类型。没有school成员变量,因而编译错误。

虚拟方法调用(Virtual Method Invocation)

正常的方法调用

Person p=new Person();
p.getInfo();
Student s=new Studnet();
s.getInfo();

虚拟方法调用(多态情况下)

Person e =new Student();
e.getInfo;//调用Student类的getInfo()方法

编译类型和运行时类型

编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法——动态绑定。

多态小节

前提

(1)需要存在继承或者实现关系、

(2)要用覆盖操作

成员方法

(1)编译时,要查看应用变量所属的类中是否有所调用的方法。

(2)运行时,调用实际对象所属的类中的重写方法。

(3)成员方法的多态性,也就是动态绑定,必须得存在于方法的重写之上

成员变量

不具备多态性,只看引用变量所属的类。

子类继承父类

(1)若子类重写了父类方法,意味着子类定义的方法彻底覆盖父类同名方法,系统不可能把父类的方法转移到子类中

(2)对于实例变量则不存在这样的现象,即使子类中定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量。

多态性应用举例

方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法

public class Test(){//把子类看做一个特殊的父类
    public void method(Person e){
        //...
        e.getInfo();
    }   
    public static void main(String[] args){
        Test t=new Test();
        Student m=new Studnet();
        t.method(m);//子类的对象m传给父类类型的参数a
    }
}

instanceof操作符

x instanceof A: 检验x是否为A的对象,返回值为boolean型。

(1)要求x所属的类与类A必须是子类和父类的关系,否则编译错误。

(2)如果x属于类A的子类B,x instanceof A值也为true。

//检验某个对象是不是类A的子类
public class Person extends Object{...}
public class Stundet extends Person{...}
public class Graduate extends Person{...}
-----------------------------------------
public void method1(Person e){
  if(e instanceof Person)
     //处理Person类及其子类对象
  if(e instanceof Student)
     //处理Student类及其子类对象
  if(e instanceof Graduate)
     //处理Graduate类及其子类对象
}

Object类

(1)Object类是所有java类的根父类(最顶层父类/基类)

(2)如果在类的声明中未使用etends关键字指明其父类,则默认父类为Object类

(3)多层继承,处于最高层的父类一定是Object类

public class Person{
  ...
}
//等价于:
public class Person extends Object{
  ...
}
//例如:
method(Object obj){...}//可以接收任何类作为其参数
Person o=new Person();
method(o);

Object类中的主要方法:

Java笔记(8)多态和对象实例化_第4张图片

你可能感兴趣的