2012-11-10 10 views
11

Lassen Sie uns sagen Java diese hierarchischen Klassen hat:Java Vererbung vs. C# Vererbung

class A 
{ 
} 
class B extends A 
{ 
    public void m() 
    { 
     System.out.println("B\n"); 
    } 
} 
class C extends B 
{ 
    public void m() 
    { 
     System.out.println("C\n"); 
    } 
} 
class D extends C 
{ 
    public static void main(String[] args) 
    { 
     A a = new D(); 
     // a.m(); // doesn't work 
     B b = new D(); 
     b.m(); 
     C c = new D(); 
     c.m(); 
     D d = new D(); 
     d.m(); 
    } 
} 

Dies ist (blind) Vervielfältigung des gleichen Code in C#:

using System; 
class A 
{ 
} 
class B : A 
{ 
    public void M() 
    { 
     Console.WriteLine("B"); 
    } 
} 
class C : B 
{ 
    public void M() // I need to use public new void M() to avoid the warning 
    { 
     Console.WriteLine("C"); 
    } 
} 
class D : C 
{ 
    public static void Main(String[] args) 
    { 
     A a = new D(); 
     // a.M(); // doesn't work  
     B b = new D(); 
     b.M(); 
     C c = new D(); 
     c.M(); 
     D d = new D(); 
     d.M(); 
    } 
} 

Wenn ich die Java ausführen Code, ich habe C-C-C, während C# B-C-C zurückgibt.

Für mich macht C# 's Ergebnis mehr Sinn, da Referenz B seine eigene Methode aufruft.

  • Was ist die Logik hinter der Entscheidung des Java Designer C-C-C statt B-C-C zu drucken? Ich meine, warum Referenz B die übergeordnete Methode in C verwendet? Was ist der Vorteil dieses Ansatzes?
  • Wie kann ich den Java-Code ändern, um B-C-C auszudrucken, genau wie C#? Ich meine, wie kann ich Java beibringen, die Methode der genauen Referenz aufzurufen, die es verwendet?
  • Wie kann ich C# -Code ändern, um C-C-C auszudrucken? Ich meine, wie kann ich C# lehren, die übergeordnete Methode aufzurufen?
+2

Es ist ein einfache Design-Problem - Java verwendet dynamischen Versand standardmäßig, während C# nicht, tut dynamisch zu bekommen Versand in C# Sie müssen eine Methode virtuell deklarieren und angeben, dass die überschreibende Methode sie tatsächlich überschreibt. – amit

+1

Die Klassen D und A haben hier keine Funktion.Sie können sie für eine kürzere (klarere) Probe weglassen. –

Antwort

10

Es ist für die virtual function Definition:

eine virtuelle Funktion oder virtuelle Methode ist eine Funktion oder Methode, deren Verhalten innerhalb einer erbenden Klasse durch eine Funktion mit der gleichen Signatur überschrieben werden kann. Dieses Konzept ist ein sehr wichtiger Teil des Polymorphismus-Teils der objektorientierten Programmierung (OOP).

In C#, sollten Sie die Methode als virtuelles, um erklären, wie zu werden außer Kraft gesetzt, in MSDN gezeigt:

Da die M Methode nicht virtuell ist, wird es b.M() auch ausführen, wenn b Variable tatsächlich eineistInstanz.

In Java ist jede Methode, mit virtueller Standard, so dass Sie, wenn Sie eine Methode überschreiben (auch ohne die @Override Anmerkung) das Verhalten der b.M() werden die d.M() sein, die das c.M() Methode Verhalten erbt.

Wie kann ich Java-Code ändern, um B-C-C auszudrucken, genau wie C#? Ich meine, wie kann ich Java beibringen, die Methode der genauen Referenz aufzurufen, die es verwendet?

Sie können dies einfach nicht in Java tun. Die Methode M in der Klasse C würde die Methode M in B überschreiben. Das Hinzufügen des Modifikators final zu B#M wird nur dazu führen, dass C oder andere B Kinder die M() Methode nicht überschreiben können.

Wie kann ich den C# -Code ändern, um C-C-C auszudrucken? Ich meine, wie kann ich C# lehren, die übergeordnete Methode aufzurufen?

Ändern die M Methode in B Klasse virtual und außer Kraft setzt es in C Klasse:

class B : A 
{ 
    public virtual void M() 
    { 
     Console.WriteLine("B"); 
    } 
} 
class C : B 
{ 
    public override void M() // I need to use public new void M() to avoid the warning 
    { 
     Console.WriteLine("C"); 
    } 
} 
6
  1. In Java sind alle Methoden, die von virtuellen Standard. Und Methoden in abgeleiteten Klassen überschreiben Methoden von Base. In C# sind sie nicht.

  2. Scheint wie Sie das nicht tun können. Sie können jedoch verhindern, dass abgeleitete Klassen diese Methode überschreiben, indem Sie sie als final deklarieren.

  3. Deklarieren Sie diese Methode mit virtual Schlüsselwort in der Basisklasse und mit override in abgeleiteten.

+0

+1 für die Antwort, aber es wäre nett, wenn Sie Ihren dritten Punkt mit C# neu definieren, die damit angegeben wird – exexzian

+3

Sie können B.m() nicht so endgültig deklarieren, wie es verhindert, C.m() zu überschreiben. – prosseek

+0

@prosseek wirklich. mein Fehler. bearbeitet. – 2kay

0

Was ist die Logik hinter der Entscheidung der Java Software-Verfasser C-C-C anstelle von B-C-C zu drucken? Ich meine, warum Referenz B die übergeordnete Methode in C verwendet? Was ist der Vorteil dieses Ansatzes?

Suchen Sie, dass Sie Methode von D-Klasse-Objekt aufrufen, die die M-Methode von C-Klasse geerbt hat. Der Referenztyp spielt in Java keine Rolle - der wichtige Teil ist die Klasse, auf die das Objekt referenziert wurde.

1

Welches ist die Logik hinter der Entscheidung des Java-Designers, C-C-C anstelle von B-C-C zu drucken?

Java macht Methoden standardmäßig virtuell. In der Vergangenheit war man sich darüber im Klaren, dass dies eine gute Praxis war und zur Zeit von Javas Geburt vielleicht auf dem Höhepunkt dieses Verständnisses war.

In diesen Tagen - obwohl viele daran festhalten - gibt es auch mehr Widerstand dagegen (zumal virtuelle Methoden die Klasse für unerwartete Unterklassenimplementierungen öffnen).

(NB. Gibt es kein richtig oder falsch hier, jeder Ansatz seine Vorteile und Nachteile.)

Wie kann ich Java-Code ändern zu drucken B-C-C wie C# ist?

Deklarieren Sie sie final.

Wie kann ich den C# -Code ändern, um C-C-C auszudrucken?

sie virtual oder abstract in der Klasse erklären, dass sie (B in der Frage) definiert, und override in untergeordneten Klassen.

+0

Sie müssen 'C's Methode mit' override' markieren. – CodesInChaos

+0

@CodesInChaos in der Tat, auch verpasst, dass abstrakt impliziert virtuell. – Richard