【学习笔记】多态

多态

即同一方法可以根据发送对象的不同而采用多种不同的行为方式

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

 

一个对象的实际类型是确定的

new Student();
new Person();

可以指向的引用类型就不确定了

Student s1 = new Student();
Person s2 = new Student();   //父类的引用指向子类的类型
Object s3 = new Student();

 

父类:

package com.oop.demo05;
​
public class Person {
    public void run(){
        System.out.println("father");
    }
}
​

子类:

package com.oop.demo05;
​
public class Student extends Person{
​
}
​

测试类:

package com.oop;
​
import com.oop.demo05.Person;
import com.oop.demo05.Student;
​
​
public class Application {
    public static void main(String[] args) {
        Person s1 = new Student();
        s1.run();
    }
}
​

image-20220718105330229

我们可以看到,虽然我们new的是Student,但是依然可以运行出父类的方法,原因是子类继承了父类的全部方法。

 

如果我们在子类中重写一下该方法

package com.oop.demo05;
​
public class Student extends Person{
    @Override
    public void run() {
        System.out.println("son");
    }
}
​

在测试类中调用一下,

package com.oop;
​
import com.oop.demo05.Person;
import com.oop.demo05.Student;
​
​
public class Application {
    public static void main(String[] args) {
        Person s1 = new Student();
        Student s2 = new Student();
        s1.run();
        s2.run();
    }
}

image-20220718105851316

 

我们发现,两个结果都运行出了“son”,原因是,子类一旦重写了父类的方法,就会执行子类的方法

 

如果在子类中写一个子类独有的方法,父类引用类型的那个变量(s1)就不能调用子类独有的方法

 public void eat(){
       System.out.println("eat");
 }

image-20220718110300712

原因是s1的类型是Person ,Person 中是没有eat方法的,所以调用不了

 

如果在父类和子类中都有该方法的话,只要子类没有重写父类,那么就调用父类的,子类重写了父类,那么就调用子类的

总结一句话,对象能执行哪些方法,主要看对象左边的类型,和右边关系不大

 Person s1 = new Student();
 Student s2 = new Student();  

Student(子类) 能调用的方法都是自己或继承父类的

Person(父类) 可以指向子类,但是不能调用子类独有的方法


多态的注意事项:

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

2.父类和子类有联系,如果类型不相同,却依旧转换的话,就会报类型转换异常 ClassCastException

3.多态存在的条件: 存在继承关系,方法需要重写,

父类的引用指向子类对象 Father f1 = new Son()

4.有些方法不能重写:

(1)static方法,它属于类,不属于实例

(2)final 常量

(3)private 方法


instanceof关键字

测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型,存在继承关系则返回true,不存在继承关系则返回false

package com.oop;
​
import com.oop.demo05.Person;
import com.oop.demo05.Student;
import com.oop.demo05.Teacher;
​
​
public class Application {
    public static void main(String[] args) {
        //Object > Person > Student
        //Object > Person > Teacher
        Object o = new Student();
        System.out.println(o instanceof Object);    //true   它是Student父类的父类
        System.out.println(o instanceof Person);    //true    它是Student的父类
        System.out.println(o instanceof Student);   //true    它本身就是Student类
        System.out.println(o instanceof Teacher);   //false   它与Student都继承Person类,但是它们没有关系
        System.out.println(o instanceof String);    //false   它继承于Object ,与Student无关
    }
}
​

image-20220718144129098

package com.oop;
​
import com.oop.demo05.Person;
import com.oop.demo05.Student;
import com.oop.demo05.Teacher;
​
​
public class Application {
    public static void main(String[] args) {
        //Object > Person > Student
        //Object > Person > Teacher
        Object o = new Student();
        System.out.println(o instanceof Object);    //true   它是Student父类的父类
        System.out.println(o instanceof Person);    //true    它是Student的父类
        System.out.println(o instanceof Student);   //true    它本身就是Student类
        System.out.println(o instanceof Teacher);   //false   它与Student都继承Person类,但是它们没有关系
        System.out.println(o instanceof String);    //false   它继承于Object ,与Student无关
        System.out.println("=================================");
        Person person = new Student();
        System.out.println(person instanceof Object);    //true   它是Student父类的父类
        System.out.println(person instanceof Person);    //true    它是Student的父类
        System.out.println(person instanceof Student);   //true    它本身就是Student类
        System.out.println(person instanceof Teacher);   //false   它与Student都继承Person类,但是它们没有关系
        //System.out.println(person instanceof String);    //编译错误
        System.out.println("=================================");
        Student student = new Student();
        System.out.println(student instanceof Object);    //true   它是Student父类的父类
        System.out.println(student instanceof Person);    //true    它是Student的父类
        System.out.println(student instanceof Student);   //true    它本身就是Student类
        //System.out.println(student instanceof Teacher);   //编译错误
        //System.out.println(student instanceof String);    //编译错误
        System.out.println("=================================");
        Person person01 = new Person();
        System.out.println(person01 instanceof Object);    //true   它是Person的父类
        System.out.println(person01 instanceof Person);    //true    它是Person本身
        System.out.println(person01 instanceof Student);   //false    它是Person的子类
        System.out.println(person01 instanceof Teacher);   //false    它是Person的子类
        //System.out.println(person01 instanceof String);    //编译错误
    }
}
​

image-20220718145415775

 


类型转换

类型转换从低向高转换不需要强制转换,直接就能转

package com.oop;
​
import com.oop.demo05.Person;
import com.oop.demo05.Student;
​
public class Application {
    public static void main(String[] args) {
        //高                 低
        Person person = new Student();
    }
}
​

如果想要从高往低转,那么就需要强制转换,比如说,person想要调用子类Student中的go方法,就需要先从Person转换成Student,才能调用

package com.oop;
​
import com.oop.demo05.Person;
import com.oop.demo05.Student;
import com.oop.demo05.Teacher;
​
​
public class Application {
    public static void main(String[] args) {
        Person person = new Student();
        ((Student)person).go();    //从Person转换为Student 
    }
}
​

 

子类转换成父类,可能会丢失自己的一些方法

 

总结:

1.父类的引用指向之类的对象

2.把子类转换成父类,向上转型

3.把父类转换成子类。向下转型 需要强制转换

4.方便方法的调用,减少重复的代码

 

 

posted @ 2022-07-18 15:15  GrowthRoad  阅读(19)  评论(0编辑  收藏  举报