java继承详解

1.继承概述

1.什么是继承,继承的好处?

继承是面向对象三大特征之一,可以让类跟类之间产生子父的关系

可以把多个子类中重复的代码抽取到父类中,子类可以直接使用,减少代码冗余,提高代码的复用性。

2.继承后子类特点

子类可以得到父类的属性以及行为,并加以使用。

子类可以在父类的基础上新增其他功能,子类更加强大。

2.继承的格式

1.父类格式

class Fu{
    //......
}

2.子类格式

class Zi extends Fu{
    //......
}

3.代码实例

class Fu{
    public void say(){
        System.out.println("hello");
    }
}


class Zi extends Fu{

}

public class Test {    //测试类
    public static void main(String[] args) {

        Zi zi = new Zi();
        zi.say();
        //输出结果为hello
    }
}

3.继承的特点

1.只能单继承,不能多继承

(用通俗的话来说,就是一个儿子不能同时有两个爸爸)

​
class A extends B{   //子类A继承父类B,正确
    
}
class A extends B,C{ //子类A继承B和C是不行的,编译器会报错

}

​

2.多个类可以同时继承一个父类

(一个爸爸可以同时有几个儿子)

​class A{    //子类B和C都继承于父类A

}
class B extends A{   
    
}
class C extends A{ 

}

​

3.可以多层继承

(爸爸是爷爷的儿子)

​
​class A{    

}
class B extends A{  //B的父类是A 
    
}
class C extends B{  //C的父类是B

}

​

​

代码实例:

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.paly1();  //结果为下棋
        zi.paly2();  //结果为打球
        zi.play3();  //结果为吃鸡
    }

}
class Ye{
    public void paly1(){
        System.out.println("下棋");
    }
}
class Fu extends Ye{
    public void paly2(){
        System.out.println("打球");
    }
}
class Zi extends Fu{
    public void play3(){
        System.out.println("吃鸡");
    }
}

值得注意的一点是,如果一个类没有写明自己的父类是谁,那么java虚拟机会默认此类的父类为Object类

4.子类可以继承父类的那些内容

1.成员变量

非私有:能            私有:能

注意:父类中私有的成员变量,子类虽然能继承,但无法调用。

(可以理解为,子类所继承的这个成员变量是一个被锁住的成员变量,而这个锁的钥匙只有父类拥有,因此自己无法使用)

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.name = "张三";   
        System.out.println(zi.name);  //结果为张三

    
        zi.money = 100;    
        //编译器会报错,会显示money 在 Extends.Fu 中是 private 访问控制
        //也就是说,这个money虽然继承过来了,但是无法使用
        System.out.println(zi.money);
    }

}
class Fu{
    String name;
    private int money;
}
class Zi extends Fu{

}

2.成员方法

非私有:能                  私有:不能

这里,要涉及一个东西叫做虚方法。

那么,什么是虚方法呢?

在类中,没有被private,static,final关键字修饰的方法统称为虚方法,而所有的虚方法统合在一起构成了虚方法表。虚方法表中的方法可以继承给子类,如果子类中再写了别的虚方法,那么就还会加在虚方法表中,可以再次继承给子类的子类。

那么,现在回到成员方法中。非私有的成员方法会继承给子类,子类可以加以调用,私有的成员方法则无法继承给子类。

​
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.say();
        //结果为hello
        zi.say1();
       //编译器会运行失败
        
        
        int a = zi.money;
        //编译器会运行失败

    }

}
class Fu{
    private  int money;
    public void say(){
        System.out.println("hello");
    }
    private void say1(){
        System.out.println("bye");
    }
}
class Zi extends Fu{

}

​

要注意,这两者虽然都会运行失败,但是报错的方式并不一样,如下:

 也就是说,被private修饰的成员变量,子类能够继承过来,但是无法进行调用,而被private修饰的成员方法,子类无法继承过来,因此显示未在子类中找到方法say1()

3.构造方法

非私有:不能                  私有:不能

1.构造方法的访问特点

 父类中的构造方法不会被子类继承。

 子类中所有的构造方法默认先访问父类的无参构造,再执行自己。

2.为什么?

子类在初始化的时候,可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。

子类在初始化之前,一定要调用父类构造方法先完成父类数据空间初始化。

3.怎么调用父类构造方法的?

子类构造方法的第一行默认语句为super(),不写仍然存在,且必须在第一行。

如果想调用父类有参构造,必须手动写super进行调用。

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        /*输出结果为 父类的无参构造
                    子类的无参构造 */
        Zi zi1 = new Zi("张三");
        System.out.println(zi1.name);
        //输出结果为张三
    }

}
class Fu{
    String name;
    public Fu() {
        System.out.println("父类的无参构造");
    }

    public Fu(String name) {
        this.name = name;
    }
}
class Zi extends Fu{
    public Zi() {
        System.out.println("子类的无参构造");
    }

    public Zi(String name) {
        super(name);
    }
}

 5.this以及super

 this:理解为一个变量,表示当前方法调用者的地址值

super:代表父类存储空间

this:

1.this.成员变量(访问本类成员变量)

2.this.成员方法(访问本类成员方法)

3.this(......)(访问本类构造方法)

super:

1.super.成员变量(访问父类成员变量)

2.super.成员方法(访问父类成员方法)

3.super(......)(访问父类构造方法)(至于这一点,本人不知道该怎么讲述,因此下述代码并未提及)

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        //输出张三


        zi.show1();
        //输出李四
    }

}

class Fu{
    String name;

    public Fu() {
    }

    public Fu(String name) {
        this.name = name;

    }
    public void show(){
        System.out.println(name);
    }
}
class Zi extends Fu{
    public Zi() {
        this("张三");//调用本类有参构造方法
        this.show();//调用本类成员方法
    }

    public Zi(String name) {
        super(name);
    }
    public void show1(){
        super.name = "李四";//调用父类成员变量
        super.show();//调用父类成员方法

    }
}

6.重写

1.什么是方法重写?

在继承体系中,子类中出现了和父类一样的方法声明,就叫做方法重写。

2.在方法重写上放可以加上@Override,用来检查方法重写是否正确。

3.重写方法的基本要求

子类重写的访问权限必须大于等于父类(访问权限:private< friendly(不写)<protected<public)

子类重写的返回类型必须小于等于父类

子类重写的方法尽量与父类中的方法保持一致

只有虚方法表中的方法可以被重写

class Fu{

    public void eat(){
        System.out.println("吃面条");
    }
    
    
    public void drink(){
        System.out.println("喝茶");
    }
    
    
    public Fu abc(){
         return null;
    }
    
    public Zi abc1(){
        return null;
    }
}
class Zi extends Fu{
    
    //加上@Override以检查重写是否正确
    @Override
    public Fu abc(){
        return null;
    }
    
    
    //父类中的访问权限是public,子类访问权限是protected,子类访问权限小于父类,编译器报错
    @Override
    protected void drink(){
        System.out.println("喝饮料");
    }
    
    
    //正确
    @Override
    public void eat(){
        System.out.println("吃米饭");
    }
    
    //由于父类中的返回类型为Zi,子类中的返回类型为Fu,所以会报错
    @Override
    public Fu abc1(){
        return null;
    }
}

以上,便是我对继承的全部见解,如有纰漏,欢迎大家指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幽幽子956

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

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

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

打赏作者

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

抵扣说明:

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

余额充值