2022.3.29 多态、instanceof、强制转换


多态

快捷键:重写方法与构造函数ALT+INS

  • 动态编译:类型:可扩展性

  • 即同一方法可以根据发送对象的不同(s1,s2)而采用多种不同的行为方式。

  • 一个对象的实际类型是确定的。但可以指向对象的引用的类型有很多(父类,有关系的类)

  • 多态存在的条件

    • 有继承关系

    • 子类重写父类方法

    • 父类引用指向子类对象

  • 多态的定义与使用格式

    • 定义格式:父类类型 变量名=new 子类类型();

  • 理解含义

    • 多态是同一个行为具有多个不同表现形式或形态的能力。

    • 多态就是同一个接口,使用不同的实例而执行不同操作。

  • 注意:多态是方法的多态,属性没有多态性。

 package com.oop.demo08;
 ?
 public class Person {
     public void run(){
         System.out.println("run");
    }
 }
 ?
 package com.oop.demo08;
 ?
 public class Student extends Person{
     @Override
     public void run() {
         System.out.println("son");
    }
     public void eat(){
         System.out.println("eat");
    }
 }
 ?
 package com.oop;
 ?
 import com.oop.demo08.Person;
 import com.oop.demo08.Student;
 ?
 //一个项目应该只存在一个main()方法
 public class Application {
     public static void main(String[] args) {
         //一个对象的实际类型是确定的
         //new Student();
         //new Person();
 ?
         //可以指向的引用类型就不确定了
 ?
         Student s1 = new Student();
         //可以指向子类,但不能调用子类独有的方法
         //编译看左边,运行看右边
         Person s2 = new Student();//父类的引用指向子类
 ?
 ?
         //对象(s1、s2)能执行哪些方法,主要看对象左边的类型(Person、Student),和右边关系不大(new Student)
         s2.run();//son,子类重写了父类的方法,执行子类的方法,子类没有重写父类的方法,执行父类的方法
         s1.run();//son
 ?
    }
 ?
 }
 ?

多态注意事项

  1. 多态是方法的多态,属性没有多态

  2. 父类和子类,有联系,不能是类型不一致(不能是这样的:String s1 = new Student(),应是引用类型变量指向new),

  3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象!father f1 = new Student();

    以下修饰的都不能被重写

    1. static 方法,属于类,他不属于实例

    2. final常量

    3. private方法

 

instanceof关键字

作用:用来判断某个对象是否属于某种数据类型。

  • instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据。 可以用来判断继承中的子类的实例是否为父类的实现

  • 类的实例包含本身的实例,以及所有直接或间接子类的实例

  • instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误

例:

 //System.out.println(X instanceof Y);能不能编译通过,取决于有没有父子关系(Object类与Student类有父子关系)
 //true:X指向的实际类型是不是Y的子类型

 

 package com.oop.demo08;
 ?
 public class Person {
     public void run(){
         System.out.println("run");
    }
 }
 ?
 package com.oop.demo08;
 ?
 public class Student extends Person {
     public void go(){
         System.out.println("go");
    }
 ?
 ?
 }
 ?
 ?
 package com.oop.demo08;
 ?
 public class Teacher extends Person{
 ?
 }
 ?
 package com.oop;
 ?
 import com.oop.demo08.Person;
 import com.oop.demo08.Student;
 import com.oop.demo08.Teacher;
 ?
 //一个项目应该只存在一个main()方法
 public class Application {
     public static void main(String[] args) {
         //Object>String
         //Object>Person>Student
         //Object>Person>Teacher
 ?
         //System.out.println(X instanceof Y);能不能编译通过,取决于有没有父子关系Object Student
         //true:X指向的实际类型是不是Y的子类型
         Object object = new Student();
         System.out.println(object instanceof Student);//true
         System.out.println(object instanceof Person);//true
         System.out.println(object instanceof Object);//true
         //当前对象object(引用变量)指向Student()类型,与Teacher()不是父子关系
         System.out.println(object instanceof Teacher);//false
         System.out.println(object instanceof String);//false
 ?
         Person person= new Student();
         System.out.println(person instanceof Student);//true
         System.out.println(person instanceof Person);//true
         System.out.println(person instanceof Object);//true
         System.out.println(person instanceof Teacher);//false
         //System.out.println(person instanceof String);编译报错
 ?
         Student student= new Student();
         System.out.println(student instanceof Student);//true
         System.out.println(student instanceof Person);//true
         System.out.println(student instanceof Object);//true
         //System.out.println(student instanceof Teacher);编译报错
         //System.out.println(person instanceof String);编译报错
 ?
    }
 ?
 }
 ?

强制转换

 package com.oop.demo08;
 ?
 public class Person {
     public void run(){
         System.out.println("run");
    }
 }
 ?
 package com.oop.demo08;
 ?
 public class Student extends Person {
     public void go(){
         System.out.println("go");
    }
 }
 package com.oop;
 ?
 import com.oop.demo08.Person;
 import com.oop.demo08.Student;
 import com.oop.demo08.Teacher;
 ?
 //一个项目应该只存在一个main()方法
 public class Application {
     public static void main(String[] args) {
         //类型之间转化:自动转化   低到高(子 父) 向上转型
 ?
         char c = 'a';
         //高   低
         int c1 = c;
 ?
         //高               低 相当于赋值,把Student()赋值给person
         Person person = new Student();
         //person.go();不能直接调用
 ?
         //与上面一样:子类转化为父类可能会丢失一些自己的方法
         Student student = new Student();
         Person p = student;
         //p.go();不能运行
 ?
 ?
         //将person这个对象强制转化为Student就可以使用Student类的方法
         Student s = (Student) person;//s用于接收
         s.go();
         
        ((Student)person).go();
 ?
    }
 ?
 ?
 }