【Java SE】(八) 继承和多态


前言

在讲述本章内容时,我们先来观察以下java中的两则代码:
在这里插入图片描述
在这里插入图片描述
所谓继承:就是对共性的一个抽取,从而实现代码的复用,就比如我们可以从上述两个类中将相同的属性抽取出来实现,如下图所示:
在这里插入图片描述
提示:子类/派生类不用必须有自己的特性,但若是没有,那么这个类和继承的意义也就没多大意义


一、继承

1.1 继承语法

修饰符 子类 extends 父类


1.2 继承的方式

1.单继承
在这里插入图片描述
2.多层继承
在这里插入图片描述
3.不同类继承同一个类
在这里插入图片描述
4.不支持多继承
在这里插入图片描述


1.3 继承中的访问限定符

访问权限大小:
public > protected > default > private
public :公开的,任何地方都能访问
prorected :同一个包中的子类、不同包中的子类都可以访问(也叫继承权限)
default :同一种包中的同一类,同一种包中的不同类
privete: 同一种包中的同一类

private访问权限代码实例在这里插入图片描述


1.4 final关键字

>编写代码时,不希望定义的类被继承或者自己定义的常量被修改,可以用final修饰

代码示例:
在这里插入图片描述


二、如何访问成员变量和成员方法

2.1 父类的成员变量和成员方法的访问

1.通过实例化对象 父类名 对象名 = new 父类名();
去访问父类自己中的成员变量和成员方法方法

class Annimals{
    public String name;
    public int age;
    public void eat(){
        System.out.println(this.name+"正在吃");
    }
}
public class Demo {
    public static void main(String[] args) {
        Annimals annimals = new Annimals();  //父类自己实例化对象
        annimals.name = "haha"; //引用父类自己的成员变量
        annimals.age = 23;
        annimals.eat(); //引用父类自己的成员方法
    }
}

2.也可以通过子类实例化对象访问父类的成员和成员变量
子类名 对象名 = new 子类名();
在这里插入图片描述
【注意】父类不可以通过实例对象访问子类中的成员变量和成员方法


2.2 子类和父类中有相同的成员变量和成员方法时访问

看到这个标题时,我们会想到这样两个问题:
1.子类和父类中可以有相同的成员变量和成员方法么?
答案是可以的,因为他们是两个类,只是是继承的关系
2.子类和父类既然可以有相同的成员变量和成员方法,那么子类访问父类中的成员变量和成员方法时,访问的是自己的还是父类中的?
接下来我们就用代码运行来验证这个问题的答案

class Annimals{
    public String name;
    public int age;
    int a = 100;
    public void eat(){
        System.out.println(this.name+"正在吃"+"父类的");
    }
}
class Dog extends Annimals{
    int a = 23;
    public void eat(){
        System.out.println(this.name+"正在吃"+"子类的");
    }
    public void run(){
        System.out.println(this.name+"正在跑");
    }
}

下图将上面的代码块中代码用子类实例化了一个对象dog去访问父类和子类中名字相同的成员变量和成员方法,有运行结果我们得出如下结论:当子类和父类中有相同的成员变量和成员方法时,子类实例化对象访问时,优先访问自己的成员变量和成员方法。也就是就近原则,自己有优先访问自己的,没有就从父类中找,都没有则编译报错。在这里插入图片描述


那么如果我们想通过子类方法中去访问父类中相同的成员变量和成员方法时,我们又应该如何访问呢?
回答这个问题前,我们现来介绍一个关键字 super,它有三种用法:
>1.super.data; ——当子类和父类中有相同成员变量时,想通过子类方法中访问父类中的成员变量使用;
2.super.func(); ——当子类和父类中有相同成员变量时,想通过子类方法中访问父类中的成员方法使用;
3.super(); ——子类构造方法时使用

通过super我们可以实现子类访问父类中相同成员变量的成员方法,如何使用,我们通过代码演示:
在这里插入图片描述
代码运行结果
在这里插入图片描述
【注意】
super只能在非静态方法中使用
只能是子类方法中访问父类的成员方法和成员变量


三、子类构造方法

3.1 super( )是什么?

1.在子类的构造方法中我们将会使用到super();它是当子类没有给出构造方法时编译器自动给出的一个不带参的构造方法,且必须放在子类方法中的第一行,若子类给出了构造方法,则编译器不会在自动给出;
2.若是要给子类构造方法必须先给父类也构造方法;因为子类实例对象时要先引用父类的构造方法,再引用自己的

当子类没有写构造方法时,如图所示:在这里插入图片描述
当子类写了构造方法时
在这里插入图片描述

3.2 继承中代码块和构造方法执行的顺序

我们都知道在没有继承的情况下,先执行静态代码块,在执行实例代码块,最后执行构造方法,且静态代码块只执行一次,那么在继承中他们之间的顺序又是怎样的呢?我们通过代码来验证:

class A{
    static{
        System.out.println("父类静态代码块");
    }
    {
        System.out.println("父类实例代码块");
    }
    public A(){
        System.out.println("父类构造方法");
    }
}
class B extends A{
    static{
        System.out.println("子类静态代码块");
    }
    {
        System.out.println("子类实例代码块");
    }
     public B(){
         System.out.println("子类构造方法");
     }
}
public class demo1 {
    public static void main(String[] args) {
        B b = new B();
        System.out.println("============");
        B c = new B();

    }
}

代码执行结果如下,通过代码验证我们知道
在这里插入图片描述


五、多态

5.1 多态的概念

多态是一种思想,它通过父类引用不同的子类对象,得到不同子类对象所表现出来的不一样的行为

5.2 多态的实现条件

1.向上转型
2.发生重写,也就是父类和子类中有同名的方法
3.通过父类调用这个重写的方法(动态绑定)

5.2.1 向上转型和向下转型

什么是向上转型?
父类引用子类对象
向上转型的用法
1.直接赋值
2.作为方法的返回值
3.作为方法的参数

1.直接赋值
在这里插入图片描述
2.作为方法的返回值
在这里插入图片描述
3.作为方法参数
在这里插入图片描述
【注意】
向上转型可以通过父类引用对象不能访问子类的特有的成员方法


5.2.1 重写

重写就是父类和子类中的有一个方法,它的方法名相同、参数列表相同、返回值相同,代码实例:
@Override 表示重写方法在这里插入图片描述
【注意】避免在构造方法中使用重写方法,容易发生动态绑定


5.2.3 通过父类引用调用重写方法

重写方法运行时才知道调用哪一个(子类或者父类中的)在这里插入图片描述

5.3 多态实例

class Card{
    public void Shape(){
        System.out.print("形状");
    }
}
class G extends Card{

    @Override
    public void Shape() {
        System.out.print("♠");
    }
}
class F extends Card{

    @Override
    public void Shape() {
        System.out.print("♥");
    }
}
class Y extends Card{

    @Override
    public void Shape() {
        System.out.print("♣");
    }
}
class H extends Card{
    @Override
    public void Shape() {
        System.out.print("♦");
    }
}
public class TestDemo2 {
    public static void doShape(Card card){ //定义一个方法,传父类的对象
        card.Shape();
    }
    public static void DOSjape(){  
        G g = new G();
        F f = new F();
        Y y = new Y();
        H h = new H();
        Card[] cards = {g,f,y,y,h,f,h,g}; //数组打印想要的顺序
        for (Card card:cards) {
            card.Shape();
        }
    }
    public static void main(String[] args) {
        doShape(new F());
        doShape(new G());
        doShape(new H());
        doShape(new Y());
        DOSjape();
    }
}

在这里插入图片描述


5.4多态的优缺点

优点:
1.有效避免使用大量if-else,降低了圈复杂度(一段代码中的循环和if-else个数)
2.可扩展能力强
缺点:
降低了代码的运行效率

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@澄夏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值