目录
🦖 3.1.2 子类和父类有同名的成员变量(关键字super)
🦖 3.2.2 子类和父类成员方法名字相同(关键字 super)
🐲 1.理解继承的概念
⚜️我们先思考一下,为什么会有继承这个概念,继承的作用是什么?
我们先看一张图片
这个图片反映了这些动物的一些共性,比如
兔子和羊都是食草动物,狮子和豹子又是食肉动物
食草动物和食肉动物,又都是动物。
每一层次都有一些共性,这样就可以比如说
各种动物是父类,下面的的这些兔子,羊等是子类
🤠父类更通用,子类更具体,子类会具有父类的一般特性也会具有自身的特性。
这样的例子放在我们java中,就比如这样
🟩所以根据这种共性,在java面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码的复用,
🟪并且在java中,它还允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,叫派生类。
⚜️ 再次强调一句话:共性抽取,实现代码复用 这是继承存在的目的 ⚜️
🐲 2.继承的语法格式(关键字extends)
既然已经知道了继承的存在意义和概念,下面就说明一下语法格式,
🟥语法格式很简单,但必须记住继承的关键字是extends
修饰符 class 子类(派生类) extends 父类(基类/超类) {
//
}
⚜️下面把前面写过的猫和狗的代码,进行共性抽取,写出派生类来
class Animal{
public String name;
public int age;
public void eat() {
System.out.println(name+"正在吃饭!");
}
}
class Dog extends Animal {
public float weight;
public void bark() {
System.out.println(name+"正在狗叫");
}
}
class cat extends Animal{
public void bark() {
System.out.println(name+"正在猫叫");
}
}
⚜️下面将现在写的继承代码,和之前写的代码进行比较
⚜️ 我们这里再强调两个必须要注意的点:
🟧(1)子类继承父类,会将父类中的成员变量或者成员方法都继承到它自己身上,
🟫(2)子类继承父类,子类必须新添加自己特有的成员,体现出和父类的相同,不然子类和父类相同了,那子类干嘛要继承呢
🐲 3.子类对父类成员的访问
⚜️下面思考这样一个问题,子类继承父类,会将父类中的成员变量和成员方法都继承下来,
那么在子类中如何访问从父类中继承下来的成员,能直接访问吗?
要回答这个问题就要把这个,分成两部分回答
🤠(1)在子类中,如何访问父类的成员变量
🤠(2)在子类中,如何访问父类的成员方法
🦄 3.1 子类中访问父类的成员变量
🦖 3.1.1 子类和父类没有同名的成员变量(直接访问)
这种很简单直接就可以访问到,看代码
//子类和父类不存在同名成员变量
class Base{
public int a;
public int b;
}
class Derived extends Base {
public int c;
public int d;
public void test(){
System.out.println(this.a);
System.out.println(this.b);
System.out.println(this.c);
System.out.println(this.d);
}
}
public class Test02 {
public static void main(String[] args) {
Derived derived = new Derived();
derived.test();
}
}
🦖 3.1.2 子类和父类有同名的成员变量(关键字super)
🟪当子类和父类有同名的成员变量时,优先访问自己的
class Base{
public int a=1;
public int b=2;
}
class Derived extends Base {
public int a=3;
public int d=4;
public void test(){
System.out.println(this.a);//3
System.out.println(this.b);//2
System.out.println(this.d);//4
System.out.println(super.a);//1
}
}
public class Test02 {
public static void main(String[] args) {
Derived derived = new Derived();
derived.test();
}
}
⚜️成员同名直接访问的话,访问的是子类自己的成员,那怎么才能访问到父类的成员呢?
🟦如果子类非要访问父类的成员,那就要使用 super 这个关键字了
🟧super 表示子类从父类中继承的这一部分成员的地址
子类访问父类成员变量
⚜️ 总结一下:
🟥(1)如果子类中有,优先访问自己的成员变量
🟩(2)如果子类中没有,就从父类中继承下来,如果父类中也没有,那就报错了
🟧(3)如果有成员变量同名,那就优先访问子类自己的
一句话,那就是:
🟪成员变量访问遵循就近原则,先访问自己,如果没有,找父类
🦄 3.2 子类中访问父类的成员方法
🦖 3.2.1子类和父类成员方法名字不同(直接调用)
这种很简单直接就可以调用到,看代码
class Base{
public int a=1;
public int b=2;
public void methodA() {
System.out.println("Base::methodA()");
}
}
class Derived extends Base {
public int a=3;
public int d=4;
public void methodB() {
System.out.println("Derived::methodB()");
}
public void test(){
methodA();//访问父类继承的methodA()
methodB();//访问字类自己的methodB()
}
}
public class Test02 {
public static void main(String[] args) {
Derived derived = new Derived();
derived.test();
}
}
🦖 3.2.2 子类和父类成员方法名字相同(关键字 super)
我们先看这样一段代码
class Base{
public int a=1;
public int b=2;
public void methodA() {
System.out.println("Base::methodA()");
}
public void methodB() {
System.out.println("Base::methodB()");
}
}
class Derived extends Base {
public int a=3;
public int d=4;
public void methodA(int val) {
System.out.println("Derived::methodA(int)"+val);
}
public void methodB() {
System.out.println("Derived::methodB()");
}
public void test(){
methodA();//Base::methodA()
methodA(100);//Derived::methodA(int)
methodB();//Derived::methodB()
}
}
public class Test02 {
public static void main(String[] args) {
Derived derived = new Derived();
derived.test();
}
}
通过观察:
⚜️子类和父类同名时,子类要访问父类的话,
🟥如果子类和父类同名方法中,构成了重载,也就是同名但参数列表不同时,就可以根据自己参数,选择合适的的方法进行访问
🟦如果子类和父类同名方法中,没有构成重载,那就是重写了,后面会提到重写
就还是会优先访问子类自己的方法。
⚜️再思考一下
🟪如果还是非要访问父类的同名成员方法,那该如何访问?
和前面那个一样还是用super.同名方法,就可以访问同名的父类成员方法了
class Base{
public int a=1;
public int b=2;
public void methodA() {
System.out.println("Base::methodA()");
}
public void methodB() {
System.out.println("Base::methodB()");
}
}
class Derived extends Base {
public int a=3;
public int d=4;
public void methodA(int val) {
System.out.println("Derived::methodA(int)"+val);
}
public void methodB() {
System.out.println("Derived::methodB()");
}
public void test(){
methodA();//Base::methodA()
methodA(100);//Derived::methodA(int)
super.methodB();//Base::methodB()
}
}
public class Test02 {
public static void main(String[] args) {
Derived derived = new Derived();
derived.test();
}
}
子类访问父类成员方法
⚜️ 总结一下:
🟥(1)如果子类中有,优先访问自己的成员方法
🟩(2)如果子类中没有,就从父类中继承下来,如果父类中也没有,那就报错了
🟧(3)如果有成员方法同名,并且构成了重载,就可以根据自己参数,选择合适的的方法进行访问。
🟦(4)如果有成员方法同名,但没有构成重载,如果直接访问成员方法就会访问子类自己的
🟫(5)如果有成员方法同名,但没有构成重载,那就要用super . 同名方法,才可以访问父类成员方法。
一句话,那就是:
🟪成员变量访问遵循就近原则,先访问自己,如果没有,找父类
🐲 4.super关键字
前面已经用过了super关键字,这里再总结一下
🟥super关键字作用:在子类方法中访问父类的成员
🟦super 只能在非静态的方法中使用:这是因为
super还有一种用法就是
🟪super() 调用父类的构造方法
🐲 5.super和this的异同点
⚜️我们在前面都提过了super和this,它们两个都可以用来访问:
成员变量和成员方法,并且都可以作为构造方法中的第一条语句,那么它们两个还有什么异同点?
相同点:
(1)在构造方法中调用,必须是构造方法中第一句,并且super和this不能同时存在
(2)都是只能在非静态方法中使用,因为这两个都需要对象
(3)都是关键字
不同点:
(1)this 是当前对象的引用,
super是子类对象从父类继承下来部分成员的引用
(2)在构造方法中一定会存在super()的调用,不管写不写都有
this()是如果不写就不调用
(3)this()用于调用自己类的构造方法
super()用于调用父类的构造方法,两个不能同时使用
(4)在非静态的成员方法中,this是用来访问本类的方法和属性
super用来访问从父类继承下来的方法和属性
🐲 6.子类对象的构造方法
先看这段代码
⚜️注意看子类继承是代码报错了,这是因为什么?
🟩前面在父类中已经写了构造方法,而在子类中又没有重新写,编译器会自动, 提供一个无参的子类构造方法进行初始化,
一个父类构造方法有参,一个子类构造方法无参,所以才会报错。
⚜️下面写一个子类对象的构造方法,
class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"正在吃饭!");
}
}
class Dog extends Animal {
public float weight;
public Dog(String name,int age,float weight) {
super(name, age);
//调用父类的构造函数,来初始化此时子类继承过来父类的属性
this.weight = weight;
}
public void bark() {
System.out.println(name+"正在狗叫");
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", weight=" + weight +
'}';
}
}
}
⚜️总结一下子类对象构造方法:
子类对象成员是由两部分组成:
🟧子类对象构造时,需要先调用父类构造方法,将从父类继承下来的成员构造完整,
然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。
⚜️提几点注意:
🤠(1)如果父类执行默认的构造方法,那么在子类构造方法的第一行默认含有super()的调用
🤠(2)如果父类构造方法是带有参数的,此时编译器给子类不会执行默认的构造方法,
这就要程序员自己给子类定义构造方法了
🤠(3)在子类构造方法中,super()调用父类构造时,必须是子类构造方法中第一条语句。
🤠(4)super()只能在子类构造方法中出现一次,并且不能和this同时出现
这里再说一次,用idea如何快速写构造方法
🐲 7.在继承关系中代码块的执行顺序
⚜️直接先看这段代码,思考一下打印顺序
class Animal{
public String name;
public int age;
static {
System.out.println("Animal的静态代码块!");
}
{
System.out.println("Animal的实例代码块!");
}
public Animal() {
System.out.println("Animal不带参数的构造方法!");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"正在吃饭!");
}
}
class Dog extends Animal {
public float weight;
static {
System.out.println("Dog的静态代码块!");
}
{
System.out.println("Dog的实例代码块!");
}
public Dog() {
System.out.println("Dog的不带参数的构造方法!");
}
public Dog(String name, int age, float weight) {
super(name, age);
this.weight = weight;
}
public void bark() {
System.out.println(name+"正在狗叫");
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", weight=" + weight +
'}';
}
}
}
public class Test01 {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
我们看一下运行结果:
⚜️下来我们再思考一下,如果把代码在运行一次,执行结果会不会变化
🟪 这个说明了,静态的代码块只会执行一次
⚜️总结一下,在继承关系中代码块的执行顺序
🟫(1)父类静态代码块先执行 —》下来执行子类静态代码块。(静态代码块最先执行)
🟦(2)父类实例代码块先执行 —》下来执行父类构造方法。 (父类要比子类执行早)
🟧(3)子类实例代码块先执行 —》下来执行子类构造方法
(实例代码块比构造方法执行早)
🟥(4)第二次实例化对象时,不论子类父类,静态代码块都不执行
🐲 8.访问限定符protected(受保护的)
将我们上一篇的表格拿过来
🤠同一个包中的同一类
class Demo {
protected int a;
public void func() {
System.out.println(a);
}
}
🤠同一包中不同的类
🤠不同包中同的子类
🐲 9.继承类型
先看一张图片
这张图片很清楚的画出了,java中的几种继承方式
下面来简单分析一下
⚜️(1)单继承
⚜️(2)多级继承
⚜️ (3)分层继承(也就是不同的类继承同一个类)
🐲 10.关键字final
🟥在前面很多地方都用到了 final 主要是用来修饰变量、成员方法以及类。
这里就简单提一下
⚜️(1)final修饰变量成员,就表示不能被修改的常量了
⚜️(2)final 修饰类,就表示这个类不能被继承
⚜️(3)修饰方法:表示该方法不能被重写
🐲 11.继承和组合的选择
⚜️本篇前面一直在写继承,那么看到这里,你理解继承了吗,继承到底是什么?
🟥继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功
能,而且可以增加它自己的新功能的能力,直接点讲就是
🟪共性抽取,实现代码复用
🟦它的关系就是 is-a
⚜️那么我们这里为什么又会提到组合,组合是什么你了解吗?
🟥复用性是面向对象的语言好处之一,
🟧而这个复用性在java代码中,有三个表现形式:继承,组合,代理,
🟫所以我们下面将要介绍一下 复用性表现形式之 组合
⚜️对于组合的理解:
🟩组合是通过对现有对象进行拼装即组合产生新的具有更复杂的功能。
🟦组合体现的是整体与部分,所拥有的关系,也就是has-a的关系
🟪也把这种方式的代码复用叫黑盒式代码复用
⚜️那么最重要的一个问题就是,继承和组合该如何选择
这里提个建议,
🟧在两种都可行的情况下,优先使用组合
🟦原因是组合比继承更加灵活,也更有助于代码维护
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/87366.html