什么是多态?
什么是多态
-
动态编译:类型:可扩展性变强
-
即同一个方法可以根据发送对象的不同而采取多种不同的行为方式
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类或者有关系的类)
-
多态存在的条件
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象
-
-
注意:多态是方法的多态,属性没有多态性
-
instanceof 类型转换~ 指的是引用类型的转换(单独讲解)
还是分为三个类:父类Perosn与子类Student以及运行(main()函数)的类Application类
package com.oop.demo06; public class Student extends Person{ @Override public void run() { System.out.println("son"); } public void eat(){ System.out.println("eat"); } }
首先是子类Student的代码
package com.oop.demo06; public class Person { public void run(){ System.out.println("run"); } }
此为父类Person的代码
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; public class Application1 { public static void main(String[] args) { //一个对象的实际类型是确定的,new啥类型就是啥类型 //new Student(); //new Person(); //但是可以指向的引用类型就不确定了:父类(也可以是祖宗类)的引用指向子类 //Student能调用的方法都是自己的或者继承父类的。 Student s1 = new Student(); //Person 为父类型,虽然可以指向子类,但是不能调用子类独有的方法 Person s2 = new Student(); Object s3 = new Student(); /* 个人理解可以理解为:右方为构造方法,父类对象通过子类的构造方法 从而可以使用子类的属性和方法,但同时子类的构造器也会调用父 类的构造器而初始化父类对象的属性和方法,因此可以视为对父类 的扩充(理解:父类的引用指向子类,也就是通过子类来调用父类 并且使父类扩展) */ //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大! s2.run();//子类重写了父类的方法,执行子类的方法即优先调重写方法 s1.eat(); s1.run(); ((Student)s2).eat();//高类型强制转换为低类型 } }
最终为Application类的代码。
对于子类Student定义了一个父类重写方法run()以及一个eat()方法。而父类Person类定义了一个run()方法。
对于Application类:首先要明确一个对象的实际类型是确定的,new什么类型就是什么类型,但是可以指向的引用类型就不确定了,一般均为确定类型的父类或者祖宗类(父类的父类...)
对于此时子类Student类能调用的方法有自己的方法以及父类能继承的方法。父类Person为父类型,虽然可以指向子类,但是不能调用子类独有的方法。只能调用子类重写自己的方法,且必须在指向子类的定义语句完成后。
个人对于定义语句(Person s2 = new Student();)的理解:等号右方为构造方法,父类Person对象通过子类Student的构造方法从而可以使用子类的方法(绝不包含属性),但同时子类的构造器也会调用父类的构造器而初始化父类对象的属性和方法,因此可以视为对父类的扩充(理解:父类的引用指向子类,也就是通过子类来调用父类并且使父类扩展)
一般来说,对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!除非左边为父类右边为子类且子类对父类的方法进行了重写。
重点:若已经完成父类指向子类的定义语句,则子类重写了父类的方法,执行子类的方法,即优先调度执行重写方法,但是不能直接执行子类的其它方法,只能执行父类自己定义的方法以及子类的重写方法。上方多态的定义:即同一个方法可以根据发送对象的不同而采取多种不同的行为方式。例如s1.run()执行结果为"son" s2.run()执行结果为"son".均为同一个方法。
对于多态的注意事项:
1.多态是方法的多态,属性没有多态 2.父类和子类,有联系 类型转换异常(ClassCastException)!如String s4 = new Student();一定报错 cast意为转换 3.多态存在的条件:有继承关系,方法需要重写,父类的引用指向子类对象 father f1 = new Son(); 1.static 方法:属于类,它不属于实例 2.final修饰的 为常量 3.private 三个符号修饰的不能重写更不可能实现多态
还有对于类型转换的提前学习:即为高类型(父类)必须通过强制转换转换为低类型(子类)才能够由高类型的对象名调用低类型的非重写方法。
即父类引用指向子类对象具体类型为:Person s2 = new Student();