抽象和继承的多态

抽象

abstract关键字用来修饰关键方法和修饰抽象类。为什么会产生抽象类呢,那是因为在代码的开发过程种,子类的种类越来越多,也越来越具体,慢慢的基本不需要使用父类的具体实现(也就是不需要new 父类后,来使用父类,而是只是把所有子类用的东西抽象出来,放到父类种,具体使用子类的实现,来实现具体的功能,就像现在没有人会new Oject()没人会直接使用Object类一样)。

抽象类

虽然不能new 父类,但是需要保留父类的构造方法,因为在子类实例化的时候需要先去调用父类的构造方。

package com.mystudy;

/**
 * @author yongchaoliu
 * @create 2020-12-30 10:47
 */
public class TestAbstract {
    
    
    public static void main(String[] args) {
    
    
        HumanA a=new HumanA("张三",12);
        System.out.println(a);
        a.updateAge();
        System.out.println(a);
    }
}
 abstract class Personss{
    
    
    protected Integer age;
    protected String name;
    public Personss (){
    
    

    }

    public Personss(String name,Integer age){
    
    
        this.age=age;
        this.name=name;
    }
    public void eat(){
    
    
        System.out.println("person eat");
    }

     @Override
     public String toString() {
    
    
         return "Personss{" +
                 "age=" + age +
                 ", name='" + name + '\'' +
                 '}';
     }
 }

 class HumanA extends  Personss{
    
    


     public HumanA() {
    
    
     }

     public HumanA(String name, Integer age) {
    
    
         super(name, age);
     }
     public Integer updateAge(){
    
    
         return this.age=11;
     }
 }

抽象方法

用abstract修饰的方法就是抽象方法
1.抽象方法所在的类一定是抽象类,反之,抽象类中不一定含有抽象方法

为什么抽象方法所在的类一定是抽象类呢? :首相我们前面说过了,抽象类是不用来实例化直接使用的,如果抽象方法所在的类不是抽象类,那就是需要实例化的(比如普通子类中含有抽象方法,那么实例化子类的时候,当调用抽象方法的时候,没有方法体,就会有问题,所以要么抽象方法必须在抽象类中,并且普通子列重写抽象方法,要么子类也是抽象类)

abstract class Person{
    
    
    protected Integer age;
    protected String name;
    **************
    /**其他普通的方法**/
    **************
    //抽象方法,没有方法体
    public abstract String walk ();
    
 }
 ***************子类重写抽象方法****************
class Human extends  Person{
    
    

     **************
    /**其他普通的方法**/
    **************
    //子类重写抽象方法
     @Override
     public String walk() {
    
    
         return "HumanA_walk";
     }
 }
********子类也是抽象类***********
abstract class  Human extends  Person{
    
    

      **************
    /**其他普通的方法**/
    **************
    
     public abstract void run();

 }

继承的多态

class Person_A{
    
    
    public void eat(){
    
    
        System.out.println("人吃饭");
    }
    public void walk(){
    
    
        System.out.println("人走路");
    }
}

class Man_A extends Person_A{
    
    
    @Override
    public void eat() {
    
    
        System.out.println("男人爱吃肉");
    }
    @Override
    public void walk(){
    
    
        System.out.println("男人走得快但是不爱逛街");
    }
    public String EarnMoney(){
    
    
        return "男人要挣钱";
    }
}
class Women_A extends Person_A{
    
    
    @Override
    public void eat() {
    
    
        System.out.println("女人也爱吃肉,但是要减肥");
    }

    @Override
    public void walk() {
    
    
        System.out.println("女人爱逛街");
    }
    public String  birthdat(){
    
    
        return  " A baby";
    }


在这里插入图片描述
可以看出使用父类的引用指向子对象时 (Person_A man=new Man_A())只能调用父类中的方法,可以看到调用子类中的独有方法是编译不过去的,那么问题来了,在我们是用多态的时候,我们传一个子类到形参是一个父类的方法是,无法调用子类独有的方法,那么多态就毫无意义了不是吗,我们可以强转一下接了调用相应的方法了

public class TestIsInstanceof {
    
    
    public static void main(String[] args) {
    
    
        Person_A man=new Man_A();
        Person_A women =new Women_A();
        test(man);

    }
    public static void test(Person_A person){
    
    
      //假设我们默认传入的就是man,就是要调用
        Man_A m=(Man_A) person;
        System.out.println(m.EarnMoney());
    }
}

在这里插入图片描述
但是这存在一个问题,如果我传入一个women呢 这个时候强转就会报错。
在这里插入图片描述

instanceof 关键字

所以就需要用到instanceof 关键字,该关键字表示是不是类的一个实例,或者说是不是该类或者是不是该类的子类。是就可以可以强转了。(需要注意的是women instanceof women 是false的)

public class TestIsInstanceof {
    
    
    public static void main(String[] args) {
    
    
        Person_A man=new Man_A();
        Person_A women =new Women_A();
        test(man);
        test(women);

    }
    public static void test(Person_A person){
    
    
      //假设我们默认传入的就是man,就是要调用
        Object o=null;
        if(person instanceof Women_A){
    
    
            Women_A w=(Women_A)person;
           o= w.birth();
        }
        if(person instanceof Man_A){
    
    
            Man_A m=(Man_A)person;
            o= m.EarnMoney();
        }
        System.out.println(o.toString());
    }
}

在这里插入图片描述

关于强转

在我们不同的类型的相互转换的时候,
**1.**低精度的可以自动转换成高精度,
**2.**高精度不能自动转换为低精度,需要用到强转

在这里插入图片描述

关于子类和父类的互相转换

1.子类可以自动转换为父类(父类的引用指向子类的实例)
2.父类不可以自动转换为子类
3.父类的引用指向子类对象后,可以强转回子类
4.子类之间不能互相转换。

在这里插入图片描述

为什么回存在这样的现象呢?说一下我的理解 ,我们从实际的使用场景中就能理解了。

1.子类可以自动转换为父类(父类的引用指向子类的实例): 实际场景中我们需要使用到多态,这就需要在父类是形参的视情况下,允许我们传入子类实例
2.父类不可以自动转换为子类: 父类转换为子类以后,当我们调用子类中特有的方法是肯定会报错,因为父类中没有子类特有的方法。
3.父类的引用指向子类对象后,可以强转回子类: 子类转为父类以后,相当于我只调用子类的部分功能,不会产生任何异常,当想转会子类时再转回来就是了,自己转自己而已。
4.子类之间不能互相转换: 本来就不是父子关系,转个毛线(父债子还,有父债大街随便抓个人还吗,哈哈哈哈)

猜你喜欢

转载自blog.csdn.net/Insect_boy/article/details/111952326
今日推荐