[JavaSE] Herança orientada a objetos

conceito de herança

Mecanismo de herança: É o meio mais importante da programação orientada a objetos para tornar o código reutilizável. Permite aos programadores estender e adicionar novas funções, mantendo as características da classe original. Isso gera uma nova classe, que é chamada de derivação. A herança apresenta a estrutura hierárquica da programação orientada a objetos e reflete o processo cognitivo do simples ao complexo. O principal problema que a herança resolve é: extração de características comuns e realização de reutilização de código.

Por exemplo: cães e gatos são ambos animais, então podemos extrair o conteúdo comum e então usar a ideia de herança para conseguir o compartilhamento.
Insira a descrição da imagem aqui
Na ilustração acima, Cachorro e Gato herdam a classe Animal. A classe Animal é chamada de classe pai/classe base ou superclasse. Cachorro e Gato podem ser chamados de subclasse/classe derivada de Animal. Após a herança, a subclasse pode ser duplicado. Usando os membros da classe pai, a subclasse só precisa se preocupar com seus próprios membros recém-adicionados ao implementá-la.

Sintaxe herdada

Em Java, se você deseja expressar o relacionamento de herança entre classes, você precisa usar a palavra-chave extends, como segue:

修饰符 class 子类 extends 父类 {
    
    
	// ...
}

Então redesenhe a cena na imagem acima usando herança:
primeiro crie o arquivo Animal.java

public class Animal{
    
    
	String name;
	int age;
	float weight;
	public void eat(){
    
    
		System.out.println(name + "正在吃饭");
	}
	public void sleep(){
    
    
		System.out.println(name + "正在睡觉");
	}
}

Em seguida, crie o arquivo Dog.java

public class Dog extends Animal{
    
    
	void bark(){
    
    
		System.out.println(name + "在汪汪叫~~~");
	}
}

Continue criando o arquivo Cat.Java

public class Cat extends Animal{
    
    
	void mew(){
    
    
		System.out.println(name + "在喵喵叫~~~");
	}
}

Por fim, crie o arquivo TestExtend.java para teste

public class TestExtend {
    
    
	public static void main(String[] args) {
    
    
		Dog dog = new Dog();
		System.out.println(dog.name);
		System.out.println(dog.age);
		dog.eat();
		dog.sleep();
		dog. Bark();
	}
}

Não há variáveis ​​de membro definidas na classe Dog. Os atributos name e age devem ser herdados da classe pai Animal. Os métodos eat() e sleep() acessados ​​por Dog também são herdados de Animal.
Perceber:

1. A subclasse herdará as variáveis ​​​​ou métodos de membro da classe pai para a subclasse.
2. Depois que a subclasse herda a classe pai, ela deve adicionar seus próprios membros exclusivos para refletir a diferença da classe base, caso contrário, não há necessidade de herdar.

Acesso aos membros da classe pai

A subclasse e a classe pai não possuem variáveis ​​de membro com o mesmo nome

public class Base {
    
    
	int a;
	int b;
}
public class Derived extends Base{
    
    
	int c;
	public void method(){
    
    
		a = 10; // 访问从父类中继承下来的a
		b = 20; // 访问从父类中继承下来的b
		c = 30; // 访问子类自己的c
	}
}

Subclasses e classes pai possuem variáveis ​​de membro com o mesmo nome

public class Base {
    
    
	int a;
	int b;
	int c;
}

public class Derived extends Base{
    
    
	int a; // 与父类中成员a同名,且类型相同
	char b; // 与父类中成员b同名,但类型不同
	public void method(){
    
    
		a = 100;
		b = 101; 
		c = 102; 
		d = 103;// 编译失败,因为父类和子类都没有定义成员变量b
	}
}
// 访问父类继承的a,还是子类自己的a?答案是自己的
// 访问父类继承的b,还是子类自己的b? 答案是自己的
// 子类没有c,访问的肯定是从父类继承下来的c

Ao acessar membros em um método de subclasse ou por meio de um objeto de subclasse:

Se a variável de membro a ser acessada existir em uma subclasse, acesse primeiro sua própria variável de membro. Se a variável membro acessada não existir na subclasse, ela será acessada herdada da classe pai. Se a classe pai não estiver definida, um erro de compilação será relatado. Se a variável-membro que está sendo acessada tiver o mesmo nome de uma variável-membro na classe pai, a sua própria será acessada primeiro. O acesso à variável membro segue o princípio da proximidade. Se você tiver uma, você tem prioridade. Caso contrário, você a encontrará na classe pai.

Os nomes dos métodos de membro são diferentes

// Base.java
public class Base {
    
    
	public void methodA(){
    
    
		System.out.println("Base中的methodA()");
	}
}
// Derived.java
public class Derived extends Base{
    
    
	public void methodB(){
    
    
		System.out.println("Derived中的methodB()方法");
	}
	public void methodC(){
    
    
		methodB(); // 访问子类自己的methodB()
		methodA(); // 访问父类继承的methodA()
		method(); // 编译失败,在整个继承体系中没有发现方法methodD()
	}
}

Resumo: Quando um método membro não tem o mesmo nome, ao acessar o método em um método de subclasse ou através de um objeto de subclasse, você acessará primeiro seu próprio método. Se você não o encontrar, você o procurará no classe pai. Se não existir na classe pai, um erro será relatado.

Métodos membros têm o mesmo nome

// Base.java
public class Base {
    
    
	public void methodA(){
    
    
		System.out.println("Base中的methodA()");
	}
	public void methodB(){
    
    
		System.out.println("Base中的methodB()");
	}
}
// Derived.java
public class Derived extends Base{
    
    
	public void methodA(int a) {
    
    
		System.out.println("Derived中的method(int)方法");
	}
	public void methodB(){
    
    
		System.out.println("Derived中的methodB()方法");
	}
	public void methodC(){
    
    
		methodA(); // 没有传参,访问父类中的methodA()
		methodA(20); // 传递int参数,访问子类中的methodA(int)
		methodB(); // 直接访问,则永远访问到的都是子类中的methodB(),父类的无法访问到
	}
}

Perceber:

Ao acessar métodos com nomes diferentes na classe pai e na subclasse por meio do objeto de subclasse, o método é primeiro pesquisado na subclasse e acessado se for encontrado. Caso contrário, o método é pesquisado na classe pai e acessado se for encontrado. Caso contrário, uma compilação erro é relatado. Ao acessar o método com o mesmo nome da classe pai e da subclasse através do objeto de subclasse, se a lista de parâmetros do método com o mesmo nome da classe pai e da subclasse for diferente (sobrecarregada), selecione o método apropriado para acessar de acordo com os parâmetros passados ​​​​pelo método de chamada, caso contrário, será relatado um erro.

super palavra-chave

A principal função desta palavra-chave é acessar membros da classe pai em métodos de subclasse.

// Base.java
public class Base {
    
    
	int a;
	int b;
	public void methodA(){
    
    
		System.out.println("Base中的methodA()");
	}
	public void methodB(){
    
    
		System.out.println("Base中的methodB()");
	}
}
// Derived.java
public class Derived extends Base{
    
    
	int a; 
	char b; 
	public void methodA(int a) {
    
    
		System.out.println("Derived中的method()方法");
	}
	public void methodB(){
    
    
		System.out.println("Derived中的methodB()方法");
	}
	public void methodC(){
    
    
		// 对于同名的成员变量,直接访问时,访问的都是子类的
		a = 100; // 等价于: this.a = 100;
		b = 101; // 等价于: this.b = 101;
		super.a = 200;
		super.b = 201;
		// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法
		methodA(); // 没有传参,访问父类中的methodA()
		methodA(20); // 传递int参数,访问子类中的methodA(int)
		// 如果在子类中要访问重写的父类方法,则需要借助super关键字
		methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),父类的无法访问到
		super.methodB(); // 访问父类的methodB()
	}
}

Perceber:

1. Super só pode ser usado em métodos não estáticos.
2. No método de subclasse, acesse as variáveis ​​​​de membro e métodos da classe pai.

Construtor de subclasse

Pai e filho, pai e filho, primeiro há o pai e depois o filho, ou seja: ao construir um objeto de subclasse, você precisa primeiro chamar o construtor da classe pai e depois executar o construtor da subclasse.

// Base.java
public class Base {
    
    
	public Base(){
    
    
		System.out.println("Base()");
	}
}
// Derived.java
public class Derived extends Base{
    
    
	public Derived(){
    
    
		// super(); // 注意子类构造方法中默认会调用父类的无参构造方	法:super(),
		// 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,并且只能出现一次
		System.out.println("Derived()");
	}
}
// Test.java
public class Test {
    
    
	public static void main(String[] args) {
    
    
		Derived d = new Derived();
	}
}
/*
* 运行的结果为:
* Base()
* Derived()
*/

No método de construção de subclasse, nenhum código sobre a construção da classe pai é escrito, mas ao construir o objeto de subclasse, o método de construção da classe pai é executado primeiro e, em seguida, o método de construção da subclasse é executado, porque: o os membros do objeto de subclasse são. Consiste em duas partes, a parte herdada da classe pai e a parte recém-adicionada da subclasse. Ao construir um objeto de subclasse, você deve primeiro chamar o construtor da classe pai para concluir a construção dos membros herdados da classe pai e, em seguida, chamar o próprio construtor da subclasse para inicializar os membros recém-adicionados da subclasse .

Perceber:

1. Se a classe pai definir explicitamente um construtor sem parâmetros ou padrão, há uma chamada super() implícita por padrão na primeira linha do construtor da subclasse, ou seja, o construtor da classe pai é chamado.
2. Se o construtor da classe pai tiver parâmetros, o usuário precisará definir explicitamente o construtor da subclasse e selecionar o construtor da classe pai apropriado para chamar o construtor da subclasse, caso contrário a compilação falhará.
3. No método de construção de subclasse, quando super(...) chama a construção da classe pai, ela deve ser a primeira instrução na construção da subclasse.
4.super(...) só pode aparecer uma vez no construtor da subclasse e não pode aparecer ao mesmo tempo.

super e isso

Tanto super quanto this podem ser usados ​​para acessar métodos de membro: variáveis ​​de membro e chamadas de outras funções de membro podem ser usadas como a primeira instrução do construtor. Então, qual é a diferença entre elas?

Mesmo ponto:

  • Todas são palavras-chave em Java.
  • Ele só pode ser usado em métodos não estáticos de uma classe para acessar métodos e campos de membros não estáticos.
  • Quando chamado em um construtor, deve ser a primeira instrução do construtor e não pode existir ao mesmo tempo.

diferença:

  • Esta é uma referência ao objeto atual, que é o objeto que chama o método de instância.Super é equivalente a uma referência a alguns membros do objeto da subclasse herdado da classe pai.
  • Em métodos de membros não estáticos, this é usado para acessar métodos e propriedades desta classe, e super é usado para acessar métodos e propriedades herdados da classe pai.
  • No método construtor: this(...) é usado para chamar o método construtor desta classe, e super(...) é usado para chamar o método construtor da classe pai. As duas chamadas não podem aparecer no método construtor ao mesmo tempo.
  • Deve haver uma chamada para super(...) no construtor, e o compilador irá aumentá-la se o usuário não escrever, mas this(...) não aumentará se o usuário não escrever.

Método de herança

Somente os seguintes métodos de herança são suportados em Java:
Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/qq_58032742/article/details/132338646
Recomendado
Clasificación