目录
多态介绍
多态 : 同一个行为具有多个不同表现形式或形态的能力 前提:有继承或实现关系 有方法重写 有父类引用指向子类对象(父类 对象名 = new 子类)
创建一个简单的多态模型
1.先制造一个接口来规定规则,以方便后续对象多态的使用
public interface Order {
//创建订单
public void creat();
//查找订单
public void find();
//取消订单
public void cancel();
//完成订单
public void finish();
}
2.分别以该接口为模板创建不同的类
public class OrderAbroad implements Order{
public void check(){
System.out.println("检查IP");
} //这里国外订单有个特殊的方法
//直接在接口处创建的类用不了
@Override
public void creat() {
System.out.println("创建国外订单");
}
@Override
public void find() {
System.out.println("查找国外订单");
}
@Override
public void cancel() {
System.out.println("取消国外订单");
}
@Override
public void finish() {
System.out.println("完成国外订单");
}
}
public class OrderChina implements Order{
@Override
public void creat() {
System.out.println("创建订单");
}
@Override
public void find() {
System.out.println("查找订单");
}
@Override
public void cancel() {
System.out.println("取消订单");
}
@Override
public void finish() {
System.out.println("完成订单");
}
}
3.创建测试类
public class Main_test {
public static void main(String[] args) {
Order The_first = null; //左边类是接口
Scanner sc = new Scanner(System.in);
int choose = sc.nextInt();
switch (choose){
case 1 :
The_first = new OrderChina();
break;
case 2 :
The_first = new OrderAbroad();
break;
}
The_first.creat(); //同一套方法,表现不同
The_first.find();
The_first.cancel();
The_first.finish();
}
}
可以看出,用接口创建对象并赋值为null时,代码允许运行,此时按照选择并输出结果
总结多态特点
成员变量:编译看定义时等号左边(父类),执行看定义时等号左边(父类) 成员方法:编译看定义时等号左边(父类),执行看定义时等号右边(子类) reason:担心你调用方法时,在父类中是一个抽象方法 对象多态 : 将方法的形参定义为父类类型, 这个方法可以接收该父类的任意子类对象 行为多态 : 同一个行为, 具有多个不同表现形式或形态的能力(类似父类被abstract修饰后) 编译时,看父类中有没有这个方法,没有则报错; 有则通过,但运行时一定会执行子类的逻辑 reason:担心你调用方法时,在父类中是一个抽象方法 多态创建对象,调用静态成员变量的时候 : (静态的成员,推荐类名进行调用) (细节 : 静态的成员可以通过对象名进行调用,这是一种假像,生成字节码文件后会自动将对象名改为类名) 多态的好处:提高了程序的扩展性 多态的弊端:不能使用子类的特有成员
转型
向上转型 从子到父(父类引用指向子类对象) Fu f = new Zi(); 向下转型 从父到子(将父类引用所指向的对象, 转交给子类类型) Zi z = (Zi) f; 可以用于掉用子类特有的方法属性(用if进行判断) 关键字 instanceof 使用格式: 对象名 instanceof 类型 判断一个对象是否是一个类的实例 通俗的理解:判断关键字左边的对象,是否是右边的类型,返回boolean类型结果
if(The_first instanceof OrderAbroad){
OrderAbroad new1 = (OrderAbroad) The_first;
new1.check();
}
(如果没有判断直接转型可能会出现的问题)转型问题: 概述:如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException
JDK.8版本后接口中允许定义非抽象方法
原因:解决接口升级的问题(直接定义抽象方法会造成接口下的子方法全部报错)
接口中默认方法的定义格式: 格式:public default 返回值类型 方法名(参数列表) {} 范例:public default void show() {} 注意事项: 默认方法不是抽象方法,所以不强制被重写 (但是可以被重写,重写的时候去掉default关键字) public可以省略,default不能省略 如果实现了多个接口,多个接口中存在相同的方法声明,子类就必须对该方法进行重写 定义该类方法后如果要在子类中调用改方法要使用 : 接口名.super.方法名;
public default void NewTer(){
System.out.println("这是一个新的特性");
}
JDK.8版本后接口中允许定义静态非抽象方法
接口中静态方法的定义格式: 格式:public static 返回值类型 方法名(参数列表) {} 范例:public static void show() {} 注意事项: 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用 public可以省略,static不能省略
//创建静态方法
public static void NewTer2(){
System.out.println("这是第二个新的特性");
}
JDK.9接口中允许定义 private 私有方法
接口中静态方法的定义格式: 格式1:private 返回值类型 方法名(参数列表) {} 范例1:private void show() {} 格式2:private static 返回值类型 方法名(参数列表) {} 范例2:private static void method() {}