大佬给推荐的韩顺平老师的课程 2021年刚刚录的船新版本!
【零基础 快速学Java】韩顺平 零基础30天学会Java
硬把从另一个讲师那里看了300多集的我拽过来 几十节课一下子爱上这个节奏了!安利!!
具有其他语言基础的盆友只需要把前几章的章节总结简单看一下 然后再去着重看需要学习的章节就可以了!
知识点分的非常清晰! 每章还有总结 这…真的是我理想中的学习资料呐!
学习笔记整理过后放到这里
本专题包括以下几个主要知识点~
本次笔记主要记录 继承 、 super关键字的内容
继承的难度比上一章的封装 要上一个台阶 但是不要慌 因为后面的多态更难QAQ
咳咳不对 因为跟着韩老师的课程学一遍 跟着这份笔记看一遍 就能看明白咯!
来通过一个实例引入
这也是比较老生常谈的继承引出方式啦(两个有很多共同点的类)
打开IDE动手写一下~
(可以看到下面两块儿的重复程度是相当滴高啊!
所以我们后面要使用继承来解决代码复用的问题~
不管怎样 先测试下能不能实现我们的案例
输出一下~
可以看到抛开代码复用性的问题 结果是符合预期的
继承可以解决代码复用 让我们的编程更加接近人类思维!
当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法。
所有子类不需要重新定义这些属性和方法,只需要通过 extends
来声明继承父类就能用这些属性和方法了!
继承的基本语法:
class 子类 extends 父类{
}
//这样继承过后 子类就会自动拥有父类定义的属性和方法
一句话概括
子类继承父类的共用属性与方法,
同时子类拥有自己的特有属性与特有方法。
使用继承改进刚才的学生考试案例
创建一个Student类解决 Graduate Pupil类
代码冗余度过高的问题
//大学生和小学生的父类 Student
public class Student {
public String name;
public int age;
private double score;
public void setScore(double score) {
//使用set快捷键 直接写好setScore方法
this.score = score;
}
public void showInfo(){
System.out.println("name " + name + " age " + age + " score " + score);
}
}
接下来两个类就好写得多啦
只需要各自写出他们独特的方法就行
public class Pupil extends Student{//让Pupil继承Student类
public void testing() {
System.out.println("小学生" + name + "正在考小学数学");
}
}
public class Graduate extends Student{
public void testing(){
System.out.println("大学生" + name + "正在考大学数学");
}
}
测试一下
(代码和之前是一样的)
public class Extends01 {
public static void main(String[] args) {
Pupil pupil = new Pupil();
pupil.name = "小黄";
pupil.age = 2;
pupil.testing();
pupil.setScore(66);
pupil.showInfo();
Graduate graduate = new Graduate();
graduate.name = "菜粥";
graduate.age = 21;
graduate.testing();
graduate.setScore(99);
graduate.showInfo();
}
}
https://www.bilibili.com/video/BV1fh411y7R8?p=289
子类继承所有的属性和方法 非私有的属性和方法可以在子类中直接访问
但是私有属性和方法不能在子类直接访问 要通过公共的方法去访问
那么我们想要用这个private
的属性和方法 咋搞呢?
如上 写一个公有的方法就好啦!
从而完成父类的初始化
这个 super()
是默认放在这个位置的(编译器做这个工作 不用写其实也可以~)
至于为啥是 super()
之后会再介绍
【1】创建子类对象的时候,不管使用子类的哪个构造器 默认情况下总会去调用父类的无参构造器
子类这边 默认调用父类的无参构造器
来创建两个子类对象 试试看
说实话这里蛮难理解的
可以去看看韩老师的视频 增强理解
【2】如果父类没有提供无参构造器 则必须在子类的构造器中用super去指定“使用父类的哪个构造器”完成对父类的初始化工作 否则 编译不会通过的哦
子类如果和之前一样 就会报错嗷
测试一下 发现与之前不同的地方在于 父类构造器的调用不再是无参的 而是有参的
https://www.bilibili.com/video/BV1fh411y7R8?p=291
这里有三种对父类某个构造器进行调用的方法
这一点在下面中体现出来了~
https://www.bilibili.com/video/BV1fh411y7R8?p=292
也就是说我们进行调用的时候 还可以调用父类的父类 父类的父类的父类……
一直可以追溯到顶级父类Object!
每个父类都会往上去找 一直找到Object
Java是单继承机制的 所以一个类只能继承一个父类
但是Java只能“单继承”么?
后面的“接口”中我们会继续探究
其实接口是可以多继承的哦!
这个is-a的逻辑关系可以说是很经典了~
(用于形容子类和父类之间的关系)
这里是非常重要的一个点哦!!!
我们通过一个案例来强化对继承本质的了解
主要看一下 “子类继承父类 创建子类对象时 内存中到底发生了什么?”
我们理解知识点的时候 要多从底层来思考!
其中为了理解继承的本质 我们要理解子类创建的内存布局(又是jvm虚拟机的一些内容)——
研究下这段代码
【1】首先分析下方法区——
【2】然后看看堆区
在分配grandpa的属性的时候 堆区会给name hobby分配地址
(其他的类同理)
这些属性会分配到常量池——
之后堆中的son对象会把地址返回给主方法的对象引用
那当son对不同类的同名属性进行访问的时候 会输出什么呢?
grandpa的name属性 father的name属性肯定不是一个啊~
这个问题引出了实例访问子类、父类同名属性的一个重要原则~
要记住这个原则嗷 我们后面在多态中还会遇到类似的概念
我们原则是:先找子类的对应属性 子类没有就去找父类 以此类推
练习在课程二刷的时候进行练习~
https://www.bilibili.com/video/BV1fh411y7R8?p=295
https://www.bilibili.com/video/BV1fh411y7R8?p=296
https://www.bilibili.com/video/BV1fh411y7R8?p=297
学习完继承的内容之后 我们对于类的学习又到达了一个新的位置——
当然了 之后还是有很重要的内容——7.多态 要进行学习!继续加油!!
在面向对象中 super用的是比较多的~
super代表父类的引用 用于访问父类的 属性、方法、构造器
这肯定啊 私有属性 听起来就不是很可以访问啦~
super.属性名
super.方法名(参数列表)
这个我们之前在继承的注意事项中刚刚说过嗷~
public A(){}
public A(String name){}
public A(String name, int age){}
//以上为父类
public B(){
//对父类的构造器进行访问!
//别忘了只能写在第一行!!
//super();
//super("jack");
super("jack", 10)
}
https://www.bilibili.com/video/BV1fh411y7R8?p=299&spm_id_from=pageDriver
这个其实也是我初学时比较困惑的一个点~
这里只要记住下面这些内容就OK了!!
拆开来下 就是
super的访问不限于直接父类 如果爷爷类和本类中有同名的成员 也可以使用super去访问爷爷类的成员!
super访问就近原则 先调用谁 就先访问谁哦!
super就是访问父类中的成员(属性/方法)
this就是访问本类中的成员