Java学习19-- 多态Polymorphism

Java中的多态(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装(Encapsulation)和继承(Inheritance)。多态允许你使用一个接口来表示多种数据类型。

在Java中,多态主要体现在以下几个方面:
Overloading+Overriding+Upcasting+Downcasting

方法的重载(Overloading):在同一个class中,method名相同,但参数列表(参数类型、个数或顺序)不同的多个方法。

public class Example {  

    void show(int x) {  

        System.out.println("整数:" + x);  

    }  

  

    void show(double x) {  

        System.out.println("双精度:" + x);  

    }  

}
方法的重写(Overriding):child class可以覆盖parent class中的method,即child class和parent class有相同名称、相同参数列表和相同return类型的method。当子类object调用这个method时,会按照child class中的method执行,而不是parent class中的同名method执行。

class Parent {  

    void show() {  

        System.out.println("Parent's show()");  

    }  

}  

  

class Child extends Parent {  

    @Override  

    void show() {  

        System.out.println("Child's show()");  

    }  

}
对象的向上转型(Upcasting):(只应用于non-static method)定义好的parent类型的变量p,虽然指向了child class,但依旧只能调用父类中独有的non-static method,而不能调用child class独有的method。

Parent p = new Child();  

p.show();  // 调用Parent类的show()方法
(Child(p)).childplay();//调用子类独有的childplay method,只能先强制转换成子类(Child(p)),然后再调用
对象的向下转型(Downcasting):将parent class类型的变量转换为子类类型child class。这需要明确地进行类型转换,并且只有在运行时该对象确实是子类的实例时,转换才会成功。引用类型之间的类型转换,关键字instanceof(参见下面举例)

if (p instanceof Child) {  //如果 object p 是Child class的子类,那么括号内为true

    Child c = (Child) p;  

    c.show();  // 调用Child类的show()方法
    //其实上面两句可以合写成一句((Child)p).show();

}

多态的主要好处是提高代码的灵活性和可扩展性。例如,你可以定义一个方法,该方法接受一个父类类型的参数,然后在运行时传递任何子类的对象。这样,你可以在不知道具体子类类型的情况下调用该方法,但方法内部会根据对象的实际类型执行相应的操作。这种特性在设计模式(如工厂模式、策略模式等)中经常被用到。

  • 多态注意事项:
    1.多态是方法的多态,属性没有多态
    2.父类和子类,有联系,类型转换异常ClassCastException
    3.存在条件:继承关系,方法需要override重写,父类引用指向子类对象

备注:不可重写override的几种情况

  1. static 方法,属于class不属于menthod
  2. final 定义了的常量比如 final double PI = 3.14;
  3. private method
  • 动态编译:类型 可扩展性
    即同一method可以根据object的不同而采用多种不同的行为方式
    一个对象的实际类型是确定的,但可以指向对象的引用类型有很多

  • 多态存在的条件

    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象

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


        //一个对象的实际类型是确定的
        // Student s1
        // Person s2

        //但是其指向的引用类型就不确定了
        Student s1= new Student();
        Person s2= new Student();

举例


package oop;
import oop.Demo06.Person;
import oop.Demo06.Student;

public class Application {

    public static void main(String[] args) {
        //一个对象的实际类型是确定的
        // s1 Student();
        // s2 Person();


        //实际类型是Student()但是其指向的引用类型就不确定了
        //Student能调用的方法都是自己的或者继承父类的
        Student s1= new Student();
		
        Person s2= new Student();//父类的引用指向子类的类型
        //Person父类,可以指向子类,但是不能调用子类独有的方法

        Object s3= new Student();
		// Object父类,可以指向子类,但是不能调用子类独有的方法,

        s1.run();//
        s2.run(); //这里父类和子类都有run method,父类触发method run,最后运行的子类student run,属于同名method override
        //如果子类重写了父类的同名方法,那么执行子类的方法就好
        //s3.run(); //object父类里面没有run method,调用run失败

        s1.eat();
        //s2.eat(); 没法使用,因为父类person里面并没有eat这个方法
        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        ((Student)s2).eat();//如果实在想用,强制类型转换成Student类型后再用

    }
}


package oop.Demo06;

public class Student extends Person{

    public void run(){
        System.out.println("student is running");
    }

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

}


package oop.Demo06;

public class Person {

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

}


运行结果:


student is running
student is running
student is eating
student is eating

多态注意事项:

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类这种关系才可以,没有关系的两种,如果强制类型转换,那么会类型转换异常,报错ClassCastException
  3. 多态存在的必要条件:继承关系,方法需要重写。父类指向子类对象!father f1 = new Son();

下面三个无法override,比如

  1. static 方法 属于class 他不属于实例
  2. final常量,一旦final卡死了,就不能再改override了
  3. private method外面链不通,也没法override

多态是method的多态 属性没有多态性

instanceof 父子关系判断关键字

instanceof是什么:
object_a instanceof class_A是 Java 中是Java中的二元运算符,用于测试一个object_a是否是指定class_A的实例或其子类child class的实例。它返回一个布尔值,如果对象是给定类型的实例,则返回 true,否则返回 false。

instanceof作用: 判断object是不是class的子类
instanceof写法:左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。

举例


package oop;
import oop.Demo06.Person;
import oop.Demo06.Student; 
import oop.Demo06.Teacher;


public class Application {
     
          Object k = new Student();
        //当前k定义为属于Object类,并且可执行student()结构的一个对象,即就是符合student类的对象。
        //Object > Person > Student
        System.out.println(k instanceof Student);//k和Student类有父子关系吗?是的。
        System.out.println(k instanceof Person);//k和Person类有父子关系吗?是的。
        System.out.println(k instanceof Object);//k和Object类有父子关系吗?是的。
        System.out.println(k instanceof Teacher);//k和Teacher类有父子关系吗?没有。
        System.out.println(k instanceof String);//k和String类有父子关系吗?没有。

        System.out.println("=================================>");

        Person y = new Student();
        //当前k定义为Person类,符合student()结构的对象,即就是符合student类的对象。
        //Object > Person > Student
        System.out.println(y instanceof Student);//k和Student类有父子关系吗?是的。
        System.out.println(y instanceof Person);//k和Person类有父子关系吗?是的。
        System.out.println(y instanceof Object);//k和Object类有父子关系吗?是的。
        System.out.println(y instanceof Teacher);//k和Teacher类有父子关系吗?没有,teacher和Student属于平级。
        //System.out.println(y instanceof String);//k和String类有父子关系吗?没有。

    }
}


package oop.Demo06;

public class Person {

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

}

package oop.Demo06;

public class Teacher extends Person{

}

package oop.Demo06;

public class Student extends Person{

    public void run(){
        System.out.println("student is running");
    }

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

}


运行结果

true
true
true
false
false
=================================>
true
true
true
false

你可能感兴趣的:(java,学习,python)