Bootstrap

java面向对象进阶篇--《继承》(万字总结,建议收藏)

一、前言

java部分连载开始,继续开始我们的java篇,前几天一直在调节web项目,刷了点力扣的题,导致java篇拉下了点。希望大家支持一下作者,制作不易。

支持一下吧(#^.^#)---------------------------------------->点我❥(^_-)

 

二、java继承的概念和特点

Java中的继承结构指的是通过 extends 关键字建立的类之间的层次关系。在这种结构中,一个类可以从另一个类继承属性和方法,并且可以通过扩展和重写来增加或修改其行为。

❥(^_-)关键概念和特点

继承结构使得代码可以更加模块化和可维护,提高了代码的复用性和灵活性,是面向对象编程的核心概念之一。

父类(基类)和子类(派生类):

  • 父类(或基类)是被继承的类。它包含了通用的属性和方法,可以被多个子类继承。
  • 子类(或派生类)通过 extends 关键字扩展自父类,可以继承父类的非私有属性和方法,并可以添加自己特有的属性和方法。

单继承:

  • Java中一个类只能直接继承自一个父类,即不支持多重继承。这种设计避免了多继承可能带来的复杂性和潜在的问题。

构造函数调用:

  • 子类的构造函数会默认调用父类的无参构造函数(如果没有显式调用其他构造函数)。如果父类没有无参构造函数,子类需要在构造函数中使用 super(...) 显式调用合适的父类构造函数。
方法重写(Override):
  • 子类可以重写父类的方法来实现自己的特定行为。重写方法必须具有相同的方法签名(方法名、参数列表和返回类型)。
访问控制:
  • 子类可以访问父类中的 public 和 protected 成员,但不能直接访问父类的 private 成员。不同包中的子类也可以访问父类的 protected 成员。
  • 子类可以覆盖父类中的 public 和 protected 方法。
继承链:
  • 当一个类继承另一个类时,它也间接继承了父类的所有祖先类。这种关系形成了一个继承链或者类层次结构。

示例理解

// 父类
class Animal {
    String name;

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

    public void speak() {
        System.out.println(name + " makes a sound");
    }
}

// 子类
class Dog extends Animal {
    public void speak() {
        System.out.println(name + " barks");
    }

    public void fetch() {
        System.out.println(name + " fetches the ball");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("Bobby");
        dog.speak(); // 输出:Bobby barks
        dog.fetch(); // 输出:Bobby fetches the ball
    }
}

在上面的例子中:

  • Animal 类是父类,定义了 name 属性和 speak() 方法。
  • Dog 类继承自 Animal 类,重写了 speak() 方法并添加了自己的 fetch() 方法。
  • Main 类展示了如何创建 Dog 对象,并调用其继承自父类和自有的方法。

三、java继承体系

Java的继承体系指的是在一个Java程序中通过继承建立起的类的层次结构。这种结构通过 extends 关键字连接不同类之间的父子关系,形成一个树形的类层次体系。

继承体系的组成和特点

根类(Root Class):

  • 所有Java类的终极基类是 java.lang.Object。即使没有显式指定一个类的父类,它也隐式地继承自 Object 类。
  • Object 类中定义了一些通用的方法,如 equals()hashCode()toString() 等,因此所有Java类都具有这些方法。

类的层次结构:

  • 在继承体系中,每个类都可以有一个父类(直接父类),而且这个父类可以有自己的父类,依此类推,形成一个类的层次结构。
  • 例如,一个应用程序可能有一个顶级的 Animal 类,然后派生出 MammalBird 等更具体的类,进一步派生为 DogCatParrot 等实际的动物类。

继承链:

  • 继承链指的是从一个类向上追溯到它的根类(Object 类)的路径。在这条链上,每个类都直接继承自它的直接父类。
  • 例如,假设有一个类 Dog 继承自 Mammal,而 Mammal 又继承自 Animal,而 Animal 继承自 Object,那么 Dog 的继承链就是 Dog -> Mammal -> Animal -> Object

多态性:

  • 继承体系中的一个重要概念是多态性。通过父类引用指向子类对象,可以实现多态,即同一个方法调用可能会在不同的子类中表现出不同的行为。这提高了代码的灵活性和可扩展性。

示例理解

注:private是私有类的意思

 

Animal类 
public class Animal {
    public void eat(){
        System.out.println("动物吃东西");
    }

    public void Drink(){
        System.out.println("动物喝水");
    }
}
 Cat类
public class Cat extends Animal {
    public void scratch(){
        System.out.println("猫抓老鼠");
    }
}
 Dog类
public class Dog extends Animal{
    public void special(){
        System.out.println("看家");
    }
}
Husky类
public class Husky extends Dog{
    public void dismantle(){
        System.out.println("拆家");
    }
}
 LiHua类
public class LiHua extends Cat{
}
Ragdoll类
public class Ragdoll extends Cat{
}
 Teddy类
public class Teddy extends Dog{
    public void touch(){
        System.out.println("蹭一蹭");
    }
}
(≧∇≦)ノText类 
public class text1 {
    public static void main(String[] args) {
        //1.创建布偶猫对象
        Ragdoll ragdoll = new Ragdoll();
        ragdoll.scratch();
        ragdoll.eat();
        ragdoll.Drink();
        //2.创建哈士奇对象
        Husky husky = new Husky();
        husky.dismantle();
        husky.eat();
        husky.Drink();
    }
}
测试结果 

 四、java子类会继承父类中的哪些内容

 

 

继承的本质是子类通过扩展父类,获得父类的结构和行为。但需要注意的是,子类只能继承父类中非私有的成员(字段、方法、构造方法、初始化块等)。私有的成员虽然存在于父类中,但对子类不可见和不可继承。

字段(Fields)

  • 子类会继承父类中的所有字段(即成员变量),包括私有、受保护、默认(包内可见)和公共字段。但是,私有字段只能在父类中访问,子类无法直接访问。

方法(Methods)

  • 子类会继承父类中的所有方法,包括私有、受保护、默认和公共方法。同样,私有方法只能在父类中访问,子类无法直接访问。

非私有构造方法(Constructors)

  • 如果父类有非私有的构造方法(无参或有参构造方法),则子类可以通过 super() 调用父类的构造方法来初始化父类的字段。

初始化块(Initialization Blocks)

  • 如果父类中有实例初始化块(即非静态的初始化块),子类会继承这些初始化块。

实现的接口(Implemented Interfaces)

  • 如果父类实现了接口,子类也会间接实现这些接口,除非子类显式地重写了这些接口的方法。

内部类(Inner Classes): 

  • 如果父类包含内部类,子类不会继承这些内部类,因为内部类并不是外部类的一部分。

 五、继承中:成员变量的访问特点

成员变量在继承中的访问特点取决于其访问修饰符。只有非私有的字段才能被子类继承和直接访问,而访问权限由字段的修饰符决定。

继承性

  • 子类会继承父类的所有非私有字段(成员变量)。这意味着如果父类中定义了字段,且字段的访问权限是受保护(protected)、默认(包内可见)或公共(public),那么子类就可以直接访问这些字段。

访问权限

  • 私有字段(private:子类无法直接访问父类中的私有字段。私有字段仅限于父类内部访问和操作。
  • 受保护字段(protected:子类可以直接访问父类中声明为受保护的字段。受保护字段在同一个包中的其他类和所有子类中可见。
  • 默认访问权限(包内可见,默认不写访问修饰符):如果父类字段没有显式地使用 privateprotected 或 public 进行修饰,则它们具有包内可见的默认访问权限。子类如果在相同的包中,可以直接访问这些字段。
  • 公共字段(public:子类无论处于哪个包中,都可以直接访问父类中声明为公共的字段。

隐藏与重写

  • 如果子类中定义了一个与父类同名的字段,那么子类的字段会隐藏(遮盖)父类的字段。这种情况下,通过子类实例只能访问子类的字段,无法直接访问父类的字段。
  • 子类可以通过 super 关键字来访问父类的被隐藏的字段,但是这种做法不太推荐,因为隐藏字段可能导致代码的可读性和维护性问题。

字段的初始化顺序

  • 当创建子类对象时,会先调用父类的构造方法来初始化父类的字段,然后再初始化子类的字段。这确保了父类字段先于子类字段被初始化。

六、继承中:成员方法的访问特点

成员方法在继承中的访问特点主要取决于其访问修饰符和是否被重写。子类可以继承和重写父类的非私有方法,但访问权限不能降低,且方法的调用由对象的实际类型决定(动态绑定)。

继承性

  • 子类会继承父类中的所有非私有方法。这包括了父类中被定义为受保护(protected)、默认(包内可见)和公共(public)的方法。

访问权限

  • 私有方法(private:子类无法继承父类中的私有方法。私有方法只能在定义它们的类内部访问,对子类和其他类都不可见。
  • 受保护方法(protected:子类可以继承父类中声明为受保护的方法。受保护方法对于子类和同一包中的其他类可见,但对于其他包中的类是不可见的,除非是子类。
  • 默认访问权限(包内可见,默认不写访问修饰符):如果父类方法没有显式地使用 privateprotected 或 public 进行修饰,则它们具有包内可见的默认访问权限。子类如果在相同的包中,可以继承并直接访问这些方法。
  • 公共方法(public:子类无论处于哪个包中,都可以继承并直接访问父类中声明为公共的方法。

方法的重写(Override)

  • 如果子类中定义了一个与父类同名、参数列表相同、返回类型兼容的方法,就称为方法的重写(override)。通过重写,子类可以提供自己的实现来替代父类的方法实现。
  • 重写的方法不能降低访问权限。例如,父类的方法是 protected 访问权限,那么子类重写的方法可以是 protected 或 public,但不能是 private 或默认(包内可见)。

动态绑定(Dynamic Binding)

  • 在运行时,根据对象的实际类型来调用方法。即使使用父类的引用指向子类对象,调用的仍然是子类重写过的方法(如果有的话)。

super 关键字

  • 子类可以使用 super 关键字来调用父类的方法,特别是在重写方法时可能需要调用父类的实现。

七、继承中:构造方法的特点

构造方法在继承中起着重要的初始化作用,子类通过调用父类的构造方法来确保父类部分的正确初始化。

子类构造方法的调用

  • 当创建子类的对象时,会先调用子类的构造方法。在子类的构造方法中,通常会隐式地调用父类的构造方法来初始化从父类继承的成员变量。如果子类构造方法中没有显式调用父类构造方法,则会默认调用父类的无参构造方法(前提是父类有无参构造方法且没有被私有化)。

默认调用父类的无参构造方法

  • 如果父类没有显式定义任何构造方法,Java会为父类提供一个默认的无参构造方法。子类的构造方法会默认调用这个无参构造方法来初始化父类的实例变量。

显式调用父类构造方法

  • 如果子类构造方法中需要调用父类的有参构造方法或者特定的无参构造方法,可以使用 super() 关键字来显式调用。super() 必须在子类构造方法的第一行,并且只能出现一次。

构造方法不可被继承

  • 构造方法本身不能被继承。子类并不继承父类的构造方法,但是子类的构造方法可以调用父类的构造方法来初始化父类部分。

构造方法的重载

  • 和普通方法一样,构造方法也可以被重载。子类可以有自己的多个构造方法,分别调用父类的不同构造方法,以初始化自身的实例变量。

构造方法的访问权限

  • 构造方法的访问权限可以是 publicprotected、默认(包内可见)或 private。子类只能继承和调用父类中具有非私有访问权限的构造方法。

八、this、super使用总结

thissuper 在Java中是两个关键的引用,分别用于引用当前对象和父类对象。它们的使用方式和场景不同,但都能帮助开发者处理对象和类之间的关系以及解决同名成员的访问问题。

使用 this 关键字:

引用当前对象

  • this 可以用来引用当前对象的实例。例如,this.someMethod() 调用当前对象的某个方法。

区分局部变量和实例变量

  • 在构造方法或者实例方法中,如果有局部变量和实例变量同名,可以使用 this 来明确指定引用实例变量。例如,this.variable 指的是当前对象的实例变量。

在构造方法中调用其他构造方法

  • 使用 this() 可以在一个构造方法内部调用同一个类的其他构造方法。这种调用必须在构造方法的第一行。

作为方法参数传递

  • 可以将 this 作为参数传递给其他方法,或者在构造方法中传递给其他构造方法。

返回当前对象

  • 在方法中使用 return this; 可以返回当前对象的引用,通常用于方法链式调用。

使用 super 关键字:

调用父类的构造方法

  • 使用 super() 可以在子类的构造方法中显式调用父类的构造方法。如果没有显式调用,Java 会隐式调用父类的无参构造方法。

访问父类的成员变量或方法

  • 可以使用 super.variable 或 super.method() 来访问父类中的成员变量或方法,特别是当子类和父类有同名成员时。

调用父类的静态方法

  • 使用 super 关键字可以调用父类中定义的静态方法,例如 super.staticMethod()

在内部类中使用

  • 如果在内部类中需要访问外部类的同名成员变量或方法,可以使用 外部类名.super.成员名 的方式访问。

 

;