Ich verweise auf die 2. Ausgabe der Java-Einführung, die Sie klar verstehen können.
Bei der Entwicklung eines Programms wird häufig eine Klasse erstellt, die der zuvor erstellten Klasse ähnelt. Derzeit ist es ineffizient, die zuvor erstellte Klasse zu kopieren und einzufügen, sodass Sie effizienten Code schreiben können, indem Sie die zuvor erstellte Klasse erben.
Hero.java
public class Hero{
private String name = "hoge";
private int Hp = 100;
public void attack(Monster m){
m.hp -= 5;
}
public void recover(){
this.Hp += 5;
}
}
SuperHero.java
public class SuperHero{
private String name = "hoge";
private int Hp = 100;
private boolean flying;
public void attack(Monster m){
m.hp -= 5;
}
public void recover(){
this.Hp += 20;
}
public void fly(){
this.flying = true;
System.out.println("Flugstatus");
}
public void land(){
this.flying = false;
System.out.println("Landezustand");
}
}
Wenn ich in diesem Code der Hero-Klasse eine neue Methode hinzufüge, muss ich diese Änderung auch in die SuperHero-Klasse ändern. Da der größte Teil des Codes zwischen der SuperHero-Klasse und der Hero-Klasse ähnlich ist, ist die Gesamtansicht schwierig und die Wartung mühsam. Verwenden Sie daher ** Vererbung **, um Codeduplizierungen zu vermeiden.
SuperHero.java
public class SuperHero extends Hero{
private boolean flying;
public void attack(Monster m){
m.hp -= 10;
}
public void recover(){
this.Hp += 20;
}
public void fly(){
this.flying = true;
System.out.println("Flugstatus");
}
public void land(){
this.flying = false;
System.out.println("Landezustand");
}
}
Durch Umschreiben wie oben beschrieben ist es möglich, eine SuperHero-Klasse zu definieren, die die Feldmethoden der Hero-Klasse erbt. In diesem Fall wird die Hero-Klasse als übergeordnete Klasse (Superklasse) und die SuperHero-Klasse als untergeordnete Klasse (Unterklasse) bezeichnet.
Java erlaubt keine Mehrfachvererbung. Insbesondere wenn es eine Hero-Klasse und eine Moster-Klasse gibt, ist es nicht möglich, eine HeroMonster-Klasse zu definieren, indem diese beiden Klassen geerbt werden. Das heißt, eine Kinderklasse kann nicht mit mehreren Elternklassen als Eltern definiert werden. Es ist möglich, die in der übergeordneten Klasse definierte Methode mit der untergeordneten Klasse zu überschreiben (als Methodenüberschreibung bezeichnet). Einige Java-Klassen dürfen nicht erben. Ein Beispiel ist die String-Klasse. Es ist auch möglich, eine Klasse zu deklarieren, die es nicht zulässt, dass sie selbst vererbt wird. Fügen Sie den letzten Operator hinzu, wenn Sie eine Klasse deklarieren.
Main.java
public final class Main{
public static void main(Strign args[]){
//Inhalt der Hauptfunktion
}
}
Um Methodenüberschreibungen zu vermeiden, fügen Sie beim Deklarieren der Methode den endgültigen Operator hinzu.
Überlegen Sie, was mit dem Verhalten der erstellten Instanz aufgrund der Vererbung passiert. Es wird anhand der oben gezeigten Hero-Klasse und der SuperHero-Klasse beschrieben. Die SuperHero-Instanz enthält eine Hero-Instanz und hat eine doppelte Struktur. Wenn ein Methodenausführungsbefehl von außerhalb der Instanz aufgerufen wird, ruft die multistrukturierte Instanz * so weit wie möglich die Methode * der untergeordneten Instanz von außen auf. Insbesondere wenn die Wiederherstellungsmethode von der SuperHero-Instanz aufgerufen wird, wird die überschriebene Methode aufgerufen und die Wiederherstellungsmethode der Hero-Instanz wird nicht aufgerufen. Beschreibt den Zugriff auf die übergeordnete Instanz. Wenn Sie sich im Flug erholen, erhalten Sie als zusätzliche Spezifikation HP um 25 Punkte. Beim Aufruf des Methodenfeldes der übergeordneten Instanz
super. Methodenname (Argument) super. Feldname
Und.
SuperHero.java
public class SuperHero extends Hero{
private boolean flying;
public void attack(Monster m){
m.hp -= 10;
}
public void recover(){
this.Hp += 20;
if(this.flying){
super.recover();
}
}
public void fly(){
this.flying = true;
System.out.println("Flugstatus");
}
public void land(){
this.flying = false;
System.out.println("Landezustand");
}
}
Wenn Sie zu diesem Zeitpunkt super.recover () mit recovery () aufrufen, wird es als this.recover () aufgerufen und Sie geraten in eine Endlosschleife. Seien Sie also vorsichtig.
Wir haben bereits erklärt, dass geerbte Instanzen eine mehrschichtige Struktur haben. Überlegen Sie als Nächstes, wie die Instanz erstellt wird. Führen Sie das folgende Programm mit Bezug auf das obige Programm aus.
Hero.java
public class Hero{
private String name = "hoge";
private int Hp = 100;
public void attack(Monster m){
m.hp -= 5;
}
public void recover(){
this.Hp += 5;
}
Hero(){
System.out.println("Heldenkonstrukteur");
}
}
SuperHero.java
public class SuperHero extends Hero{
private boolean flying;
public void attack(Monster m){
m.hp -= 10;
}
public void recover(){
this.Hp += 20;
}
public void fly(){
this.flying = true;
System.out.println("Flugstatus");
}
public void land(){
this.flying = false;
System.out.println("Landezustand");
}
SuperHero(){
System.out.println("SuperHero Konstruktor");
}
}
Main.java
public class Main{
public static void main(Strign args[]){
SuperHero sh = new SuperHero();
}
}
Zuerst wird der übergeordnete Instanzteil erstellt, und dann wird der untergeordnete Instanzteil außen erstellt. Schließlich ruft die JVM automatisch den SuperHero-Klassenkonstruktor auf. Das Ausführungsergebnis ist wie folgt.
Ausführungsergebnis
Heldenkonstrukteur
SuperHero Konstruktor
Beachten Sie, dass der Konstruktor der Hero-Instanz, die die innere Instanz ist, ebenfalls aufgerufen wird. Dies liegt daran, dass die Java-Regel lautet: "Alle Konstruktoren müssen zu Beginn den Konstruktor der internen Instanz aufrufen."
SuperHero.java
public class SuperHero extends Hero{
.
.
.
SuperHero(){
super();
System.out.println("SuperHero Konstruktor");
}
}
Der Compiler fügt automatisch super () ein.
Ein Konstruktor, der nicht im übergeordneten Instanzteil definiert ist, kann vom Konstruktor im untergeordneten Instanzteil aufgerufen werden, was zu einem Fehler führt. Insbesondere wird es unter Verwendung der Klasse Mensch und der Klasse Soldat beschrieben.
Human.java
public class Human{
private String name;
private int Hp;
private int Mp;
Human(String name){
this.name = name;
this.Hp = 100;
this.Mp = 100;
}
Human(String name, int hp, int mp){
this.name = name;
this.Hp = hp;
this.Mp = mp;
}
}
Human.java
public class Soldier{
.
.
.
}
Main.java
public class Main{
public static void main(Strign args[]){
Soldier soldier = new Soldier();
}
}
In diesem Code hat die Soldier-Klasse keinen Konstruktor, daher wird der Konstruktor der übergeordneten Klasse Human-Klasse aufgerufen. Die Human-Klasse verfügt jedoch nicht über einen Konstruktor ohne Argumente, sodass dieser Code zu einem Fehler führt. Um dies zu verhindern, rufen Sie den Konstruktor mit Argumenten im Konstruktor der Soldier-Klasse zwangsweise auf, um das Problem zu lösen.
Human.java
public class Soldier{
.
.
.
Soldier(){
super("hoge");
}
}
Richtige Vererbung ist Vererbung nach dem "is-a-Prinzip".
Untergeordnete Klasse ist eine übergeordnete Klasse (untergeordnete Klasse ist Teil der übergeordneten Klasse)
Wie im oben gezeigten Code erläutert, ist die SuperHero-Klasse Teil der Hero-Klasse. Es ist ein Fehler, dass die Hero-Klasse Teil der SuperHero-Klasse ist. Vererbung ist eine nützliche Funktion, aber eine falsche Vererbung kann zu programmatischen Inkonsistenzen und der Unfähigkeit führen, die Vielfalt zu nutzen.
Eine abstrakte Klasse ist eine Klasse mit einem abstrakten Methodenfeld. Eine konkrete Klasse, die von einer abstrakten Klasse erbt, muss die in der abstrakten Klasse definierten Methoden überschreiben. Wenn Sie mehrere abstrakte Klassen erben, können Sie dies auch realisieren, indem Sie die abstrakten Klassen als Schnittstellen definieren (Details sind 2.3). Die Bedeutung der Existenz abstrakter Klassen und Methoden ist ein Material für die effiziente Erstellung sicherer Programme, wenn die Anzahl der Entwickler in Zukunft zunimmt. Um ein konkretes Beispiel zu nennen: Wenn Sie mit der Entwicklung ohne abstrakte Klasse fortfahren, wird der Inhalt einer bestimmten Methode zu diesem Zeitpunkt möglicherweise nicht festgelegt, und der Inhalt der Methode wird möglicherweise leer gelassen. Wenn ein anderer Entwickler diese Methode sieht, weiß ich nicht, ob der Inhalt neu geschrieben werden muss. Wenn es jedoch als abstrakte Methode definiert ist, muss es überschrieben werden, sodass ersichtlich ist, dass der Inhalt neu geschrieben werden muss. Daraus können Sie sich mit der abstrakten Methode sicher entwickeln.
Character.java
public class Character{
.
.
public abstract void atttack(Monster m);
}
Die Angriffsmethode ist in einer Klasse enthalten, die die Zeichenklasse erbt.
Character.java
public abstract class Character{
.
.
public abstract void atttack(Monster m);
}
Definieren Sie eine Klasse als abstrakte Klasse, um die Erstellung unvollständiger Klasseninstanzen zu verhindern.
In Java können abstrakte Klassen mit einem besonders hohen Abstraktionsgrad speziell als Schnittstellen behandelt werden. Als Bedingung, um als Schnittstelle zu behandeln
Es gibt.
Creature.java
public interface Creature{
public abstract void run(); //öffentliche Zusammenfassung kann weggelassen werden
}
Wenn Sie eine Variable in der Schnittstelle definieren, wird public static final ergänzt und als Konstante behandelt. Gehen Sie beim Implementieren der Creature-Klasse wie folgt vor.
Pig.java
public class Pig implements Creature{
public void run(){
System.out.println("Schwein rannte weg");
}
}
Durch die Definition der Schnittstelle
Es gibt einen Verdienst.
Recommended Posts