Java学习八、继承和多态

一、继承

当不同类之间存在大量重复成员时,可以使用继承来进行共性抽取,实现代码复用。

继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性 的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了 由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。

基础语法

表示类之间的继承关系,需要借助extends关键字。这样子类就会将父类中的成员变量或成员方法继承到子类中了。

修饰符 class 子类 extends 父类{

        //...

}

子类中访问父类的成员变量

当子类和父类有同名的成员变量时,优先访问子类的。

1.子类和父类不存在同名成员变量

public class Base {
    int a;
    int b;
}
 

public class Derived extends Base{
    int c;
    public void method(){
        a = 10;    // 访问从父类中继承下来的a
        b = 20;    // 访问从父类中继承下来的b
        c = 30;    // 访问子类自己的c

   }
}

2.子类和父类成员变量同名

public class Base {
    int a;
    int b;
    int c;
}

public class Derived extends Base{
    int a;              // 与父类中成员a同名,且类型相同
    char b;             // 与父类中成员b同名,但类型不同

    public void method(){
        a = 100;        // 访问父类继承的a,还是子类自己新增的a?
        b = 101;        // 访问父类继承的b,还是子类自己新增的b?
        c = 102;        // 子类没有c,访问的肯定是从父类继承下来的c
        // d = 103;     // 编译失败,因为父类和子类都没有定义成员变量b

   }
}

在子类方法中通过子类对象访问成员时:

如果访问的成员变量子类中有,优先访问自己的成员变量。

如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。

如果访问的成员变量与父类中成员变量同名,则优先访问自己的。

子类中访问父类的成员方法

public class Base {
     public void methodA(){
         System.out.println("Base中的methodA()");
     }
}

public class Derived extends Base{
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
   }
    
    public void methodC(){
        methodB();         // 访问子类自己的methodB()
        methodA();         // 访问父类继承的methodA()
        // methodD();     // 编译失败,在整个继承体系中没有发现方法methodD()

   }
}

总结:成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。

通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用 方法适传递的参数选择合适的方法访问,如果没有则报错。

如果子类和父类的方法同名,且构成重载,则按照合适的方法进行访问。

如果没有构成重载,则是构成重写,会优先访问子类的方法。

如果我们想访问父类的同名成员方法,可以使用super.同名方法,就可以访问父类的成员方法了。

二、super关键字

作用:在子类方法中访问父类的成员

super只能在非静态的方法中使用,因为

静态方法不依赖对象。super从父类中访问成员对象,与static修饰矛盾,所以不能。

还可以使用super调用父类的构造。

super和this的异同:

相同点:

1. 在构造方法中调用时,必须是构造方法的第一句,且this和super不能同时存在

2. 都只能在非静态方法中使用

3. 都是关键字

不同点:

1. this是当前对象的引用,super是子类对象从父类继承下来部分成员的引用

2. 在构造方法中一定会存在super()的调用,不管有没有显式写,都有。而this()不写就不会调用

3. this()用于调用自己类的构造方法,super()用于调用父类的构造方法,两个不能同时使用

4. 在非静态的成员方法中,this是用来访问本类的方法和属性的,super是用来访问从父类继承下来的方法和属性的。

三、子类对象的构造方法

子类对象构造时,先要帮助父类成员进行初始化。

因为子类对象成员由   继承下来的父类成员 和 子类自己新增的成员   构成,所以子类对象构造时,需要先调用父类构造方法,将从父类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。

要注意:

1. 如果父类执行默认的构造方法,那么子类构造方法的第一行默认含义super()的调用

2. 如果父类构造方法是带有参数的,此时编译器给子类不会执行默认的构造方法,这时就需要程序员自己给子类定义构造方法。

3. 在子类构造方法中,super()调用父类构造时,必须是子类构造方法的第一条语句。

4. super()只能在子类构造方法中出现一次,并且不能和this同时出现。

四、继承中,代码的执行顺序

先执行父类和子类中的静态代码块(注意,静态代码块只执行一次),再执行父类的实例和构造,再执行子类的实例和构造。

五、final关键字

final修饰变量,则表示其不能被修改了。

final修饰类,则表示这个类不能被继承(final写在类的最前面)。

final修饰方法:表示该方法不能被重写。

六、多态

多态即同一行为具有不同的表现形式或形态。

也就是对于同一个接口,使用不同的实例可能会执行不同的操作。

6.1 实现多态的条件

1. 必须在继承体系里

2. 必须有通过父类的引用来调用重写的方法

3. 子类必须要对弗雷中的方法进行重写

重写和重载的区别?

重载是。

重写是。

重写的条件:

1. 子类和父类的方法返回类型一样。但是其实被重写的方法返回值类型可以不同,但是必须要具有父子关系。(子类的返回值也可以不同,但要满足,子类的返回值和父类的返回值是父子类关系,也可以叫协变关系。)

2. 方法的方法名一样

3. 方法的参数类型、个数、顺序相同

4. static方法不能被重写

5. private修饰的方法不能被重写。

6. 子类访问修饰符权限要大于等于父类

重写的方法,记得使用@Override注解来进行合法性校验。这样我们没有完成重写时,编译器会报错。

重写是子类和父类的一种多态性表现。

重载是一个类的多态性表现。

6.2 静态绑定和动态绑定

静态绑定:也称前期绑定(早绑定),即在编译时,根据用户所传递实参类型,就确定了调用哪个方法。例如:函数重载。

动态绑定:也称为后期绑定(晚绑定)。在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用哪个类的方法。

6.3 向上转型和向下转型

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

列宁格勒的街头

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

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

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

打赏作者

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

抵扣说明:

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

余额充值