多态性
多态性是发送信息给某个对象,让该对象自行决定响应何种行为。通过将子类对象引用赋值给超类对象引用变量来实现多态方法调用
多态性通过允许同一界面指定一类动作减少了程序的复杂度,编译器工作就是选择适用于各个情况的特定动作,而程序员则无需手动进行选择,使用者仅仅是记得以及利用这个统一的界面
多态性形成的三个条件:
有继承,父类定义方法,子类重写方法父类的引用指向子类的对象可以使用参数传递时多态,也可以直接创建对象时多态
package com.yan5;
public class Test1 {
public static void main(String[] args) {
A1 a = new A1();
// 多态性是发送消息给某个对象,让该对象自行决定响应何种行为
a.pp();
a.pp(12);
/*
* 多态形成的三个必要条件:
* 有继承,父类定义方法,子类重写方法
* 父类的引用指向子类的对象
* 可以使用参数传递时多态,也可以直接创建对象时多态
*/
}
}
class A1 {
public void pp() {
System.out.println("A1...pp无参");
}
public int pp(int kk) {
System.out.println("A1...pp--int");
return 100;
}
}
多态可以用三个定义和两个方法总结
三个定义:父类定义子类构建、接口定义实现类构建和抽象类定义实体类构建
两个方法:方法重载和方法重写
多态分为两种:
编译时多态:方法的重载
运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态
package com.yan5;
//有继承,父类定义方法,子类重写方法
public class Test2 {
public static void main(String[] args) {
//父类的引用指向子类的对象
A2 aa=new B2();
aa.pp(); //new谁就是谁
//aa对象有编译期类型和运行时类型2种类型,
/*
* 编译期类型就是编译器所识别的类型,识别aa对象为A2类型,因为A2种并没有cc方法所以编译报错
*
* aa.cc();编译失败
*
* 运行时类型就是在运行期间aa的具体的类型,new谁就是谁
*
* 在代码种需要进行强制类型转换,才可以调用子类种特殊定义的方法
*/
((B2)aa).cc();
}
}
class A2 {
public void pp() {
System.out.println("A2...pp");
}
}
class B2 extends A2 {
public void pp() {
System.out.println("B2...pp");
}
public void cc() {
System.out.println("B2...cc");
}
}
类间多态和类内多态
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作
类间多态性
父子类之间的一种多态性,例如:动物 x=new 猫()
package com.yan2;
public class Test3 {
public static void main(String[] args) {
动物 x2 = new 动物();
动物 x1 = new 猫();
动物 x3 = new 狗();
// x2.play();因为没有定义
// x1.play(); 编译器进行语法检查时,是按照声明的类型进行检查
if(x1 instanceof 猫) { //instanceof运算符用于判断某个对象是否为指定的类型,是为true
((猫)x1).play();
}
}
}
class 动物 {
}
class 猫 extends 动物 {
public void play() {
}
}
//语法种没有任何报错,但是不符合逻辑现实。编程是对现实世界的模拟体现
class 狗 extends 猫 {
}
方法调用中的限制: 针对一个类对象有两种类型,一种称之为编译期类型,编译时系统识别对象的类型,”动物 x = new 猫()”在编译时,系统识别x是动物类别的,所以只能调用动物类定义的方法,而不能调用猫中特殊的方法。另外一种称之为运行时类型,也就是当程序运行系统识别的类型,new谁就是谁覆盖的方法一定不能是private的
类内多态性
在一个类对象上调用相同名称的方法,但是参数不同时执行不同的动作
public class Test2 {public static void main(String[] args) {A2 a=new A2();// a.pp();// a.pp(12);a.pp("shitou");}}class A2 {public void pp() {System.out.println("A2.pp()");}public void pp(Integer k) {System.out.println("A2.pp(int)");}public void pp(Object kk) {System.out.println("A2.pp(String)");}public void pp(int k1,String k2){}public void pp(String k1,int k2){}}
方法名称相同,参数不同,和返回值类型无关参数个数不同参数类型不同参数顺序不同。注意不同参数名称顺序不同
最佳匹配原则
package com.yan2;
public class Test6 {
public static void main(String[] args) {
B6 bb=new B6();
// A6 bb=new B6();
// bb.pp("yanjun");
bb.pp(123);
}
}
class A6{
public int pp() {
System.out.println("A6...Non");
return 10;
}
public void pp(Integer kk) {
System.out.println("A6...Integer");
}
public void pp(int k) {
System.out.println("A6...int");
}
public void pp(Number kk) {
System.out.println("A6...Number");
}
public void pp(Object kk) {
System.out.println("A6...Object");
}
}
class B6 extends A6{
public void pp(String name) {
System.out.println("B6...String");
}
}