解析java中的继承

解析java中的继承

1 含义

在符合当代社会的约定俗成的逻辑的情况下,很多类具有相同的属性和方法,我们这些共有的属性和方法抽象成一个类后,通过extends关键字使得很多类与抽象成的类建立父子关系,其中很多类称为子类,抽象出来的类叫做父类

2 为什么需要继承?

2.1 减少代码的冗余,提高复用性

例如Chinese类Russian类都有namesexage这三个属性,

那么如果每个类都写的话,就是如下所示的代码

Chinese类

public class Chinese{
   private String name;
   private String sex;
   private int age;

    public Chinese() {
    }

    public Chinese(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Russian类

public class Russian {
    private String name;
    private String sex;
    private int age;

    public Russian() {
    }

    public Russian(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

我们不难发现这两个类里面的一些属性其实是公共的,可以抽象成一个People类

改进后的代码如下所示

Chinese类

public class Chinese extends Peple{
  
}

Russian类

public class Russian extends Peple{

}

People类

public class Peple {
    private String name;
    private String sex;
    private int age;

    public Peple() {
    }

    public Peple(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

我们可以发现此时的Chinese类和Russian类清爽多了,咱们也可以通过set和get方法去写入和读取它

2.2 便于功能的扩展

例如你想对某些类加上一个功能,没学继承之前你可能得这么干

Chinese类

public class Chinese {
    private String name;
    private String sex;
    private int age;
    //你想要增加weight体重这个属性,你得在Chinese里面增加weight这个属性
    private int weight;

    public Chinese() {
    }

    public Chinese(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight = weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
//你得增加Chinese类中增加和修改体重的方法
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

Russian类

public class Russian{
    private String name;
    private String sex;
    private int age;
    //你想要增加weight体重这个属性,你得在Russsian里面增加weight这个属性
    private int weight;

    public Russian() {
    }

    public Russian(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight = weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你得增加Russian类中增加和修改体重的方法
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

你会发现当需要增加一个属性时,你得将每个需要加上的类中加上这个属性以及它的set/get方法,非常的麻烦,当我们使用继承后,改进后的代码如下所示

Chinese类

public class Chinese extends Peple{
  
}

Russian类

public class Russian extends Peple{

}

People类

public class Peple {
    private String name;
    private String sex;
    private int age;
    //你想要增加weight体重这个属性,只需要在Chinese类和Russian类的父类去增加属性即可
    private int weight;
    public Peple() {
    }

    public Peple(String name, String sex, int age,int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

这样去增加和修改共有的属性是很方便的

2.3 为多态性的使用,提供了前提

3 如何使用继承

3.1 判断两个类之间是否存在继承关系的方法

a.判断两个类是否存在逻辑层面上面的父子关系

例如Dog类和People类,显然两者之间不存在逻辑层面的上的父子关系,人不可能是狗的亲生父亲,狗也不可能是人的亲生父亲。

b.公式法: A类 is B类或者B类 is A类是否成立,其中后者为父类,前者为子类

例如Dog类和People类,既不满足Dog is People,也不满足People is Dog 而Animal类和Dog类,满足Dog is Animal,因此Animal类和Dog类存在继承关系,其中Animal是父类,Dog是子类

3.2 语法

class A extends B{
   //其中A类为子类,派生类
   //B类为父类,超类,基类
}

3.3 规则

3.3.1 子类继承父类,调用构造方法时,一定会需要先调上父类的其中的任意一个构造方法,再调用自己的构造方法,若子类构造方法里面没有调用父类的,那么就会报错。注意:子类无参会默认调用父类无参构造的(默认会使用super()😉)
错误示例代码
Chinese类
public class Chinese extends Peple{
    public Chinese() {
    }
}
People类
public class Peple {
    private String name;
    private String sex;
    private int age;
    private int weight;

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
    private void print(int count){
        System.out.println("父类中的私有化方法"+count);
    }
    public void show(int count){
        print(count);
    }

}

Test02类
public class Test03 {
    public static void main(String[] args) {
        Chinese c=new Chinese();
    }
}
错误示例代码运行截图

在这里插入图片描述

在这里插入图片描述

正确示例代码
Chinese类
public class Chinese extends Peple{
    public Chinese() {
        //实际上是在首行省略了super();
        System.out.println("调用Chinese类里面的无参构造方法");
    }

}

People类
public class Peple {
    private String name;
    private String sex;
    private int age;
    private int weight;

    public Peple() {
        System.out.println("调用People类的无参构造方法");
    }

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

Test03类(测试类)
public class Test03 {
    public static void main(String[] args) {
        Chinese c=new Chinese();
    }
}
正确示例代码运行截图

在这里插入图片描述

3.3.2 一个类只能继承于一个父类,但一个父类可以被多个子类继承.(单继承)
错误示例代码(一个类继承了多个父类)

Chinese类

public class Chinese extends Peple,Creature{
    public Chinese() {
        //实际上是在首行省略了super();
        System.out.println("调用Chinese类里面的无参构造方法");
    }
}
错误示例代码在编译器里面的错误提示

在这里插入图片描述

正确示例代码(1个父类可以有多个子类,一个子类仅有一个父类)

Chinese类

public class Chinese extends Peple{
    public Chinese() {
        //实际上是在首行省略了super();
        System.out.println("调用Chinese类里面的无参构造方法");
    }

}

Russian类

public class Russian extends Peple{
    public Russian() {
        System.out.println("调用Russian类里面的无参构造方法");
    }
}

People类

public class Peple {
    private String name;
    private String sex;
    private int age;
    private int weight;

    public Peple() {
        System.out.println("调用People类的无参构造方法");
    }

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

Test03类

public class Test03 {
    public static void main(String[] args) {
        Chinese c=new Chinese();
        System.out.println("-------------------");
        Russian russian=new Russian();
    }
}
正确示例代码运行截图

在这里插入图片描述

3.3.3 子类继承父类时,会将所有属性和方法,都复制到自己的空间,这是一个副本,对子类进行数据的修改时,不会对父类的数据造成影响
a 公开属性
示例代码

Chinese类

public class Chinese extends Peple{
    public Chinese() {
        //实际上是在首行省略了super();
    }

}

People类

public class Peple {
    public String name;
    private String sex;
    private int age;
    private int weight;

    public Peple() {
    }

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }


    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

Test03类

public class Test03 {
    public static void main(String[] args) {
        Peple p=new Peple();
        Chinese c=new Chinese();
        //只需要子类修改了继承过来的属性和方法,看是否对父亲原来的属性和方法造成影响
        c.name="张三";
        p.name="李四";
        System.out.println("子类中,名字为:"+c.name);
        System.out.println("父类中,名字为:"+p.name);
//        System.out.println("-------------------");
//        Russian russian=new Russian();
    }
}

示例代码运行截图

在这里插入图片描述

b 公开方法
示例代码

Chinese类

public class Chinese extends Peple{
    public Chinese() {
        //实际上是在首行省略了super();
    }

}

People类

public class Peple {
    private String name;
    private String sex;
    private int age;
    private int weight;
    public int count;
    public Peple() {
    }

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
    public void test(int count){
       this.count=count;
    }

}

Test03类

public class Test03 {
    public static void main(String[] args) {
        Peple p=new Peple();
        Chinese c=new Chinese();
        //只需要子类修改了继承过来的属性和方法,看是否对父亲原来的属性和方法造成影响
        System.out.println("调用父类公开方法时");
        p.test(6);
        System.out.println("调用子类公开方法时");
        c.test(2);
        System.out.println("子类中,count的值为:"+c.count);
        System.out.println("父类中,count的值为:"+p.count);
//        System.out.println("-------------------");
//        Russian russian=new Russian();
    }
}

示例代码运行截图

在这里插入图片描述

c 私有属性
示例代码

Chinese类

public class Chinese extends Peple{
    public Chinese() {
        //实际上是在首行省略了super();
    }

}

People类

public class Peple {
    private String name;
    private String sex;
    private int age;
    private int weight;
    public Peple() {
    }

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

}

Test03类

public class Test03 {
    public static void main(String[] args) {
        Peple p=new Peple();
        Chinese c=new Chinese();
        //只需要子类修改了继承过来的属性和方法,看是否对父亲原来的属性和方法造成影响
        System.out.println("使用父类对象进行更改名字属性时");
        p.setName("张三");
        System.out.println("使用子类对象进行更改名字属性时");
        c.setName("王五");
        System.out.println("父类中,name属性值为: "+p.getName());
        System.out.println("子类中,name属性值为:"+c.getName());
    }
}

示例代码运行截图

在这里插入图片描述

d 私有方法
示例代码

Chinese类

public class Chinese extends Peple{
    public Chinese() {
        //实际上是在首行省略了super();
    }

}

People类

public class Peple {
    private String name;
    private String sex;
    private int age;
    private int weight;
    public Peple() {
    }

    public Peple(String name, String sex, int age, int weight) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.weight=weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //你只需要在People里面写一次get/Set方法就行,这样Chinese类和Russian类都可以调用
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
    private void print(int count){
        System.out.println("父类中的私有化方法"+count);
    }
    public void show(int count){
        print(count);
    }

}

Test03类

public class Test03 {
    public static void main(String[] args) {
        Peple p=new Peple();
        Chinese c=new Chinese();
        //只需要子类修改了继承过来的属性和方法,看是否对父亲原来的属性和方法造成影响
        System.out.println("使用父类对象调用show方法时");
        p.show(8);
        System.out.println("使用子类对象调用show方法后");
        c.show(100);
        System.out.println("再次使用父类对象调用show方法时");
        p.show(8);
    }
}

示例代码运行截图

在这里插入图片描述

3.3.4 类可以多层继承,直接继承的叫做父类,不直接继承的叫做间接父类

例如如下代码,类A继承类B,类B继承类C,类A也继承了类C的属性和方法,我们把类B叫做类A的直接父类,把类C叫做类A的间接父类

A类

class A extends B{
    
}

B类

class B extends C{

}

C类

class C{

}
3.3.5 如果一个类没显示的声明其父类时即类名后面没有接上extends关键字时,那么此类继承于java.lang.Object
示例代码
Chinese类
public class Chinese {
    public Chinese() {
    }

}
Test03类
public class Test03 {
    public static void main(String[] args) {
        Chinese c=new Chinese();
        System.out.println(c.toString());
        System.out.println(c.getClass());
    }
}

分析

示例代码中的toString方法和getClass方法都是从Object处继承来的,因此才可以调用它

示例代码运行截图

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SSS4362

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

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

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

打赏作者

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

抵扣说明:

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

余额充值