原来Java的继承也可以这么简单

    什么是继承?看一下百度百科的解释:

继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。

Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

嗯哼?是不是有些飘飘然,似懂非懂的感觉?这就对了,咱们不看他的解释。

首先说一下继承出现的目的:让类可以复用和扩展

复用和扩展:简单来说就是把你写的优秀的代码,不仅仅用于单个地方,让它能在多个地方使用,在必要的时候,可以对类的功能进行扩充。

在讲继承之前,我们有必要先了解一下组合,组合和继承的语法和行为大多是相似的。由于他们是利用现有类型生成新的类型,所有这么做是非常有意义的。

其实在之前写代码的时候,我们已经用到了组合。

什么时候用到了呢?

当然是在我们在一个类中去 new另外一个类对象的时候啊!上面已经说了,组合和继承的语法和行为大多是相似的,所以组合也是一种代码复用的体现。

好了,组合了解过了,我们来扯一下继承吧

  • 继承

继承呢,是所有的OOP(面向对象)语言不可缺少的一部分,在创建一个类时,即使你不写extends关键字,你也在使用着继承,这是因为Java提供了一个标准的根类(Object类),如果你不显示的使用继承,那么默认就是继承的Object类。

继承的语法规则:

一个类不能同时继承多个父类,即不能同时出现两个extends关键字,但是它可以传递继承(B继承A,C继承B,C同样可以拥有A的方法和属性,可以理解为爸爸的爸爸依然是你的家人),最后我们将会看到传递继承的代码;

代码演示:

public class Student {

}
public class Student extends People {

}

这表明Student类继承了People类(可以理解为爹和儿子),当你这么写时,Student类会自动得到基类(父类)中的所有域和方法(这里的所有包括private修饰的属性和方法,但是由于private属性只允许本类访问,所以在Student类中无法直接访问,但是本质上还是继承了)

下面改动一下Student 和 People类,演示一下Student继承People中的属性和方法

public class People {
    public String name;
    public Integer age;
    private double money;

    public void m3() {
        System.out.println("People类中的m3()方法,public....");
    }

    private void m4() {
        System.out.println("private....")
    }

    public void m1() {
        System.out.println("People类中的m1()方法,public....");
    }
}

我们把年龄和名字设置成公开的,money设置成私有的(毕竟money不外漏嘛,还是设置成私有的比较安全,不然让别人看见咱那6位密码保护着2位数的money,怪不好意思的),设置三个方法 m1(public),m3(public),m4(private),不要问m2跑哪了,他可能走丢了吧。。。。

再写个子类,为了方便,我们直接在子类中写一个主函数,方便测试!

public class Student extends People {

    public void m5() {
        System.out.println("m4()....");
    }
    public void m2() {
        System.out.println("Student类中的方法....");
        m1();
        m5();
    }

    public static void main(String[] args) {
        m5();
        Student student = new Student();
        student.m3();
        student.m2();
        student.name = "fmh";
        student.age = 18;
    }
}

由于我们继承了People类,所以就会获得该类中的所有域和方法(不要较真私有属性和方法,它也被继承了,或者你直接认为它不可继承),看看m2(),偷偷跑着来了,在m2()中可以直接调用m1(),这说明什么?不清楚?不是吧,那你看m5(),直接在m2()调用了,这不就说明,继承了来自People类中的方法了吗!

  • 初始化基类(父类)

由于现在涉及了两个类,所以要他们是怎么初始化的呢?

继承并不是简单地把基类的属性和方法复制了一份给子类,而是在创建子类对象的时候,该对象包含了一个基类的子对象。这个包含的子对象和你直接创建基类的对象是一样的(这也是为什么上边代码利用子类对象,可以调用父类方法的原因)。直接创建和包含于子对象的区别就在于,直接创建来自于外部,而基类的子对象被包装在了子类对象的内部(类似于你家附近的小水沟中有鱼,鱼可被认为是包含在水中,你把水抽干,自然也能得到鱼了,这个比喻可能不太恰当,但是由于本人语文太差,实在想不到好的比喻了)。

修改一下代码,看看继承关系,初始化是怎么执行的

public class People {
    public People() {
        System.out.println("People()....");
    }
}
public class Teacher extends People{
    public Teacher() {
        System.out.println("Teacher()....");
    }
}
public class Student extends Teacher {
    public Student() {
        System.out.println("Student()....");
    }

    public static void main(String[] args) {
        Student student = new Student();
    }
}

看下运行结果

为什么会这样呢?明明就创建了一个Student对象,怎么初始化了三个构造方法呢?

这就说明:构建过程,是从基类向外扩散开的,即在你创建子类对象的时候,基类的的构造方法先执行。

这里的原因呢,就是在你调用构造方法的时候,编译器会给你自动加一个super();让你在初始化子类的构造方法之前,先初始化父类的无参构造器,如果你的基类自己写了有参构造,却忘了写无参构造,那么这个super();就需要你显示的写出来了,并传递相应的参数,否则编译器可能会骂你!

这个super()我就不再演示了,自己动手写一下代码,印象更深刻!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值