继承-多态中多态的使用

多态的格式

代码当中体现多态性,其实就是一句话:父类引用指向子类对象
格式:父类名称 对象名=new 子类名称()
或者:接口名称 对象名称=new 实现类名称()

public class demo01Polymorphism  {
    public static void main(String[] args) {
        //使用多态的写法,左侧父类的引用,只想了右侧子类的对象
        Fu obj=new Zi();
        obj.method();
        obj.methodFu();
    }
}

创建一个父类名为Fu

public class Fu {
    public void method(){
        System.out.println("父类方法!");
    }
    public void methodFu(){
        System.out.println("父类特有方法!");
    }
}

创建一个子类名为Zi
子类中重写父类中的方法,然而父类中有一个方法是父类特有的,再我们调用子类方法时,可以通过创建对象方式调用,使用多态:父类名称 对象名=new 子类名称(),就如同“猫是动物”这个说法一样,右侧子类被当作子类使用

public class Zi extends Fu{
    @Override
    public void method(){
        System.out.println("子类方法!");
    }
}

多态中成员变量使用特点

访问成员变量的两种方式:
1.直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则往上找【注意成员变量不能覆盖重写的】不会往下查找
2.间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找

public class demo01MultiField {
    public static void main(String[] args){
        Fu obj=new Zi();
        System.out.println(obj.num);
        //System.out.println(obj.age);子类中有一变量age,但是我以Fu obj=new Zi()写法,只会在父类中查找,不会往下查找
        obj.showNum();//子类没有覆盖重写,那么就是父类中的变量,如果子类覆盖重写,那就是子类中的变量
    }
}

创建一个父类名为Fu

public class Fu {
    int num=10;
    public void showNum(){
        System.out.println(num);
    }
}

创建一个子类名为Zi

public class Zi extends Fu{
    int num=20;
    int age=12;

    @Override
    public void showNum() {
        System.out.println(num);
    }
}

当我们在间接通过成员方法访问成员变量时,如果在子类中覆盖重写了成员方法,那么调用方法访问的成员变量时子类的,如果没有覆盖重写方法,那么访问的成员变量就是Fu类中的成员变量,不糊往下查找

多态中成员方法使用特点

在多态的代码当中,成员方法访问规制时是:看new的是谁就优先用谁,没有则往上找
口诀:编译看左,运行看右,在编译时,如果左边有这个类中有这个方法,那么编译正确,再运行,如果运行时子类中有这个方法
那么就是用这个子类的方法,如果没有,就向上寻找。
对比:
成员变量:编译看左边,运行看左边
成员方法:编译看左边,运行看右边

public class demo02MoltiMethod {
    public static void main(String[] args) {
        Fu obj=new Zi();
        obj.method();//父子都有method,优先用new后面的Zi类中的方法
        obj.methodFu();//子类中没有。而父类中有,所以使用的父类中的方法
        //编译看左边,左边是Fu,Fu当中没有methodZi方法,所以编译报错。
       // obj.methodZi();错误写法
    }
}

创建一个父类名为Fu

public class Fu {
    int num=10;
    public void showNum(){
        System.out.println(num);
    }
    public void method(){
        System.out.println("父类方法使用");
    }
    public void methodFu(){
        System.out.println("父类特有方法执行");
    }
}

创建一个子类名为Zi

public class Zi extends Fu {
    int num =10;
    int age=12;

    @Override
    public void showNum() {
        System.out.println(num);
    }

    @Override
    public void method() {
        System.out.println("子类方法使用");
    }
    public void methodZi(){
        System.out.println("子类特有方法执行");
    }
}

对象的向上转型

1.对象的向上转型其实是多态的写法:
格式:父类名称 对象名称=new 子类名称()
含义:右侧创建一个子类对象把它当作父类来看待使用。
注意事项:向上转型一定是安全的。是从小范围转换成大范围。
类似于double num=100;//这是真确的,int—>double,自动类型转换。

public class demo01 {
    public static void main(String[] args) {
        //对象的向上转型就是:父类引用指向子类的对象。
        Animal animal=new Cat();
        animal.eat();
    }
}

创建父类名为animal

public abstract class Animal {
    public abstract void eat();
}

创建子类Cat

public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

结果输出为“猫吃鱼”,向上转型即为多态

向下转型

向上转型一定是安全的,没有问题的正确的,但是有一个弊端:
对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。
如果要调用子类的特有方法,那么就要向下转型【还原】
2.对象向下转型其实是一个还原的动作。
格式:子类名称 对象名=(子类对象名称)父类对象;这有点想强制转换的格式
含义:将父类对象【还原】成为本来的子类对象。
注意事项:1.必须保证对象本来创建的时候就是要还原的类,那样才能还原成为本类
2.如果对象创建的时候本来不是本类,现在非要向下转化成本类就会报错!

public class demo01 {
    public static void main(String[] args) {
        Animal animal=new Cat();
        animal.eat();
        //animal.catmouse();一旦向上转型之后,不能再调用子类特有方法,如同例子中,猫抓老鼠,但是动物不一定能抓老鼠
        //向下转型,进行”还原“动作
        Cat cat=(Cat) animal;
        cat.catchMouse();//这样运行结果就是猫抓老老鼠,如果转换成为其他类就会报错成为ClassCastException

    }
}

创建父类Animal

public abstract class Animal {
    public abstract void eat();
}

创建子类Cat

public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼 ");
    }
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

如何知道一个父类引用的对象

如何才能知道一个父类引用的对象,本来是什么子类?
格式:对象 instenceof 类名称
这将会得到一个boolean值结果,也就是判段前面的对象能不能当作后面类型的实例。

public class demo02Instenceof {
    public static void main(String[] args) {
        Animal animal=new Cat();
        animal.eat();
        //如果希望调用子类特有方法需要向下转型
        //判断一下父类引用是不是Cat
        if(animal instanceof Dog){
            Dog dog=(Dog)animal;
        }if(animal instanceof Cat){
            Cat cat=(Cat)animal;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值