java继承多态深度理解

1.继承的概念:

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,

或子类从父类继承方法,使得子类具有父类相同的行为。

当然我们可以从生活中的例子来理解继承,就像儿子继承父亲的家业还是什么,或者说徒弟继承师傅的衣钵.

生活中的继承:

1.1 继承的作用

在java中继承的作用简而言之就是: 完成共性的抽取,实现代码复用,更重要的是有了继承才有了方法的覆盖和多态机制

它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。

继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程.

在Java中被继承的类叫做父类(超类)或者是基类,而继承的类叫做子类或者是派生类

如果一个类不继承任何类默认继承Object类,Object类是所有类的父类,每个类都直接或间接继承Object类,并且java只支持单继承,并不支持多继承,但是接口却支持多继承.

什么可以继承:

除了静态的不支持继承,构造方法不支持继承,final修饰的不支持继承,私有的不支持继承以外,其他的都可以继承

 如图,我们就说B继承A, B为子类,A为父类

1.2子类和父类中成员变量和方法的调用

 在当前情况,可以通过子类引用直接访问父类的实例,因为B继承了A

那子类也可以有自己特有的特有属性,并且可以与父类成员变量相同,但是如果实例方法的方法名,形参列表,方法修饰符完全相同,那就构成方法的重载(重写)了.

与方法重载的不同,方法重载在同一类中,并且只要求方法名相同,而形参列表不同.

而方法重写发生在具有继承关系的子类中

需要注意的是,子类重写父类方法的时,重写方法不能有比父类更严格的权限访问

 当前子类doSome()方法的权限是default低于public ,所以子类的doSome()必须要public 修饰

 

1.2.1子类实例变量与父类重名

当实例变量与局部变量重名时,我们用this表示当前对象的引用,来表示实例变量,

同理当子类实例变量与父类实例变量重名时我们使用super来访问父类中的实例变量

 上面是访问本类中的name,下面是访问父类中的name

this与super

this与super有很多的相似之处

this

1.在局部变量与实例变量冲突时,this表示当前对象的引用,使用this表示实例变量

2.在构造方法中调用其他的的构造方法,并且只能出现在调用构造方法中的第一行,并且只能出现一次.

super

1.子类与父类的实例变量名冲突时,使用super访问父类中的实例方法和实例变量,与this不同

,super只是一个关键字,并不是引用

2.在进行创建子类对象是,必须先对父类对象进行初始化,然后才对子类对象进行初始化

那就需要调用父类中的构造方法,这时可以使用super调用父类中的构造方法,并且跟this调用构造方法一样,只能出现在第一行,也就说在调用构造方法时,this和super不能同时出现

注意:在访问实例变量时可以使用this,this可以访问从父类继承的实例变量和子类特有的实例变量,但是当父类与子类的实例变量重名时,this只能访问到子类的实例变量,此时只能用super访问父类的实例.

上图是this和supe在访问实例变量的范围 

1.2 继承中的执行顺序

在实例化一个子类对象时,会首先执行父类中的静态代码块,然后是子类的静态代码块,并且静态方法是在类加载的时候执行的,并且只执行一次,然后是父类的实例,在到父类的构造方法,最后是子类的实例,和构造方法.

public class Test {
    public static void main(String[] args) {
        B b = new B();

    }
}
class A{
    String name;
    int age;
    static {
        System.out.println("父类静态块");
    }
    {
        System.out.println("父类实例代码块");
    }

    public A() {
        System.out.println("父类构造");
    }

    public void doSome(){
        System.out.println("父类方法");
    }
}
class B extends A{
    String name;
    static {
        System.out.println("子类静态块");
    }
    {
        System.out.println("子类实例块");
    }

    public B() {

        System.out.println("子类构造");
    }
    public void method(){
        System.out.println(name);
        System.out.println(super.name);
        System.out.println("子类方法");
        super.doSome();
    }
    public void doSome(){
        System.out.println("子类重写");
    }
}

这是以上代码的执行结果,可以看出执行顺序就是先父后子,先静态后实例,最后构造

2.多态

通俗来讲就是一种事物的不同形态,例如H₂O在液态的时候是水,气态的时候是水蒸气,固态的时候是冰.

在java中多态就是父类型引用指向子类型对象

2.1 类型转换

向上转型(自动类型转换) :子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象. (小转大)

public class Test {
    public static void main(String[] args) {
        Animal a=new Cat();

    }
}
class Animal{
    String name;
    public void eat(){
        System.out.println("动物会吃");
    }
}
class Cat extends Animal{
    int age;
    public void eat(){
        System.out.println("猫吃鱼");
    }
}

上面就是把Cat转成Animal是向上转型(自动类型转换)

向下转型(强制类型转换): 向下转型是把父类对象转为子类对象

Cat c=(Cat)a

这就是向下转型(强制类型转换)

需要注意的是只有是具备继承关系的才可以进行类型转换,并且都是在子类的基础上进行类型转换的,不可以对父类对象进行转型

 

 

上面都是错误的向下转型,是类型准换异常的

 为了避免向下转型的错误,在进行向下转型的时候使用instanceof关键字

instanceof

instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。

instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。

语法格式:

if(变量名 instanceof 类型)

 每次在进行向下类型转换是都是用instanceof来进行判断

2.2多态访问实例变量和实例方法

2.2.1访问实例变量

访问实例方法当前是什么类型就访问该类实例对象的变量

简而言之就是编译看左运行也看左

public class Test {
    public static void main(String[] args) {
        Animal a=new Cat();
        System.out.println(a.name);
       

    }
}
class Animal{
    String name="动物";

    public void eat(){
        System.out.println("动物会吃");
    }
}
class Cat extends Animal{
    int age;
    String name="猫";
    public void eat(){
        System.out.println("猫吃鱼");
    }
}

 这里打印的结果是动物

2.2.2访问实例方法

简而言之就是编译看左运行看右

此时需要对父类中的方法进行重写(覆盖)

 可以看到父类引用,最后执行的是Cat中的eat方法

以上就是本次的全部内容,谢谢大家

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qm_hu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值