您现在的位置是:首页 > 经典句子

JAVA系列 小白入门参考资料 继承

作者:纳雷武时间:2024-05-02 17:10:54分类:经典句子

简介  文章浏览阅读1.5k次,点赞59次,收藏23次。Java 继承相关的知识点和 易错提醒

点击全文阅读

目录

1. 为什么需要继承

2. 继承的概念

3. 继承的语法

4. 父类成员访问 

        4.1 子类中访问父类的成员变量

                  1. 子类和父类不存在同名成员变量

                  2.  子类和父类成员变量同名  

4.2 子类中访问父类的成员方法 

1. 成员方法名字不同

2. 成员方法名字相同  

​5. super关键字

6. 子类构造方法

7. super和this  

相同点

不同点

8. 继承关系的执行顺序

9. 继承方式 

单继承

多层继承 

不同类继承同一个类 

10. final关键字


1. 为什么需要继承

Java 中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是现实世界错综复杂,事物之间可能会存在一些关联。因此需要一些程序设计来解决这个问题。 下面通过代码来发现问题
//定义一个狗类class Dog{    public String name;    public int age;    public String color;    public void eat() {        System.out.println(this.name + "在吃东西");    }    public void run() {        System.out.println(this.name + "在跑");    }}//定义一个鸟类class Bird{    public String name;    public int age;    public String color;    public void eat() {        System.out.println( this.name + "在吃东西");    }    public void fly() {        System.out.println( this.name + "在飞");    }}public class blog {    public static void main(String[] args) {        Dog dog = new Dog(); //创建对象        //初始化        dog.name = "小灰";        dog.age = 10;        dog.color = "灰色";        //调用方法        dog.eat();        dog.run();        Bird bird = new Bird();        bird.name = "小花";        bird.age = 10;        bird.color = "花色";        bird.eat();        bird.fly();    }}

我们可以看到Dog类和Bird类中有以下相同的成员变量和成员方法

    public String name;    public int age;    public String color;    public void eat() {        System.out.println(this.name + "在吃东西");    }

因此 我们为了节省代码,提高代码的复用性,我们引入了继承这个概念。


2. 继承的概念

继承 (inheritance) 机制 :是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性 的基础上进行 扩展,增加新功能 ,这样产生新的类,称 派生类 。继承呈现了面向对象程序设计的层次结构, 体现了 由简单到复杂的认知过程。继承主要解决的问题是: 共性的抽取,实现代码复用


3. 继承的语法

修饰符 class 子类名 extends class 父类名 {       // ... }
关键字是 extends

因为 小狗和小鸟 都是属于动物,他们有自己的年龄、颜色等等属性。也会吃东西等等相同动作,并且作为宠物都会给他们给予名字 。

因此 我们创建一个新的类(Animals) 作为父类,并将 这些相同的属性和动作作为成员变量和成员方法  放入其中。

以下代码为使用继承之后。我们可以明显的看到 代码少了很多。

并且在现实生活中我们只需要关注子类特有的属性和方法即可

class Animals{    public String name;    public int age;    public String color;    public void eat() {        System.out.println(this.name + "在吃东西");    }}class Dog extends Animals{    public void run() {        System.out.println(this.name + "在跑");    }}class Bird extends Animals{    public void fly() {        System.out.println( this.name + "在飞");    }}public class blog {    public static void main(String[] args) {        Dog dog = new Dog();        dog.name = "小灰";        dog.age = 10;        dog.color = "灰色";        dog.eat();        dog.run();        Bird bird = new Bird();        bird.name = "小花";        bird.age = 10;        bird.color = "花色";        bird.eat();        bird.fly();    }}

4. 父类成员访问 

4.1 子类中访问父类的成员变量

        1. 子类和父类不存在同名成员变量

class Father {    public int a = 10;    public int b = 20;}class Son extends Father {    public int c = 30;    public void Method(){        System.out.println(a);        System.out.println(b);        System.out.println(c);    }}public class Test {    public static void main(String[] args) {        Son son = new Son();        son.Method();    }}

程序正常运行,并且子类可以访问父类的成员变量,并打印值。 


2. 子类和父类成员变量同名  

使用关键字 super

我们先来看 如果  子类和父类成员变量同名 会输出什么?

class Father {    public int a = 10;    public int b = 20;}class Son extends Father {    public int a = 100;  // 如果子类有  先访问子类的。  子类没有的  才会去看父类是否有    public int c = 30;       public void Method(){        System.out.println(a);        System.out.println(b);        System.out.println(c);    }}public class Test {    public static void main(String[] args) {        Son son = new Son();        son.Method();    }}

由此我们可知,会输出子类的 同名成员变量。

那么如果我们非要访问 父类变量呢?

就是前面所提的 super 

class Father {    public int a = 10;    public int b = 20;}class Son extends Father {    public int a = 100;    public int c = 30;    public void Method(){        System.out.println(super.a);// 输出父类的 a        System.out.println(this.a);// 谁调用 就输出谁的a         System.out.println(b);        System.out.println(c);    }}public class Test {    public static void main(String[] args) {        Son son = new Son();        son.Method();    }}

在子类方法中 或者 通过子类对象访问成员时 : 1.如果访问的成员变量子类中有,优先访问自己的成员变量。 2.如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。 3.如果访问的成员变量与父类中成员变量同名,则优先访问自己的。 成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找

4.2 子类中访问父类的成员方法 

1. 成员方法名字不同

class Father{    public void Func() {        System.out.println("Func");    }}class Son extends Father{    public void Func2() {        System.out.println("Func2");    }    public void Func3() {        Func();        Func2();    }}public class Test {    public static void main(String[] args) {        Son son = new Son();        son.Func3();    }}


2. 成员方法名字相同  

 我们在Son类中添加一个   和 Father类一模一样Func成员方法,看结果如何?

class Father{    public void Func() {        System.out.println("Func");    }}class Son extends Father{    public void Func() {        System.out.println("Son::Func");    }    public void Func2() {        System.out.println("Func2");    }    public void Func3() {        Func();        Func2();    }}public class Test {    public static void main(String[] args) {        Son son = new Son();        son.Func3();    }}

结果是 子类有同名方法,先调用自己的方法。 

如果想要在子类调用 父类中的同名成员方法,还是需要用到关键字super

//在此就不过多 赘写代码了 //基于上面的代码//这里我将最核心的代码修改部分,单提了出来 public void Func3() {        this.Func();        super.Func();        this.Func2();    }


5. super关键字

作用:在子类方法中访问父类的成员。

如何使用,前面代码已经展示了其作用。

注意事项: 1. 只能在非静态方法中使用 2. 在子类方法中,访问父类的成员变量和方法。 

6. 子类构造方法

父子,即先有父,后有子。所以在我们的代码中,当我们想创建子类对象时,要先调用和实现父类的构造方法,然后再实现子类构造方法 

在之前的代码中,虽然父类和子类都没有显式的定义构造方法。但其实 子类中 有隐藏的代码

public class Father {    public Father(){    System.out.println("Father()");    } }public class Son extends Father{    public Son(){    // super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),    // 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,    // 并且只能出现一次    System.out.println("Son()");  }}

下面代码是父类已经有定义好的构造方法

class Animals{    public String name;    public int age;    public String color;    //父类的构造方法    public Animals(String name, int age, String color) {        this.name = name;        this.age = age;        this.color = color;    }    public void eat() {        System.out.println(this.name + "在吃东西");    }}class Dog extends Animals {    //子类的构造方法    public Dog() {        super("小罗",10,"白色");    }    public void run() {        System.out.println(this.name + "在跑");    }}class Bird extends Animals {    //子类的构造方法    public Bird(String name, int age, String color) {        super(name, age, color);    }    public void fly() {        System.out.println( this.name + "在飞");    }}public class Blog {    public static void main(String[] args) {        Dog dog = new Dog();// 根据构造方法           //第一种初始化方式        dog.name = "小灰";        dog.age = 10;        dog.color = "灰色";        dog.eat();        dog.run();        Bird bird = new Bird("小辣椒",10,"红色");// 根据构造方法  //第二种初始化方法        bird.eat();        bird.fly();    }}

注意:

1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法 2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。 3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。 4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

7. superthis  

super  和  this  都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句,那他们之间有什么区别呢?

相同点

1. 都是Java中的关键字 2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段 3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

不同点

1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用 2. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性 3. 在构造方法中:this(...)用于调用本类构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造 方法中出现 4. 构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)用户不写则没有

8. 继承关系的执行顺序

在之前的学习中我们知道了

代码块相关的知识点 

1.静态代码块先执行,并且只执行一次,在类加载阶段执行

2.当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行

class Persons{    String name;    int age;    public Persons(String name, int age) {        this.name = name;        this.age = age;        System.out.println("Person构造方法被调用");    }    {        System.out.println("Person实例代码块被调用");    }    static {        System.out.println("Person静态代码块被调用");    }}class Students extends Persons{    public Students(String name, int age) {        super(name, age);        System.out.println("Students构造方法被调用");    }    {        System.out.println("Students实例代码块被调用");    }    static {        System.out.println("Students静态代码块被调用");    }}public class job {    public static void main(String[] args) {        Students students = new Students("小罗",18);        Students students2 = new Students("小米",18);    }}

无奖竞猜:大家猜一下输出结果是什么?

通过分析执行结果,得出以下结论: 1、父类静态代码块优先于子类静态代码块执行,且是最早执行 2、父类实例代码块和父类构造方法紧接着执行 3、子类的实例代码块和子类构造方法紧接着再执行 4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

9. 继承方式 

单继承


多层继承 

 


不同类继承同一个类 

 最重要的是,不可以同一个类继承不同的类


10. final关键字

final关键可以用来修饰变量、成员方法以及类。

1.修饰变量或字段,表示常量(即不能修改)


2.修饰类:表示此类不能被继承


3.修饰方法:表示该方法不能被重写 

 

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句