C#とJavaの継承の違い

このQ&Aのポイント
  • C#とJavaの継承の挙動には違いがありますか?
  • C#とJavaの継承では、サブクラスのメソッドの実行結果が異なる場合があります。
  • C#では親クラスのメソッドを実行するため、サブクラスのメソッドではなく親クラスのメソッドが表示されることがあります。一方、Javaではサブクラスのメソッドが実行されます。
回答を見る
  • ベストアンサー

C# と Javaの継承の違い

http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_004/csharp_abc02.html 上記、URLの記事にて Person someone = new Taro();  → TaroはPersonのサブクラス Console.WriteLine( someone.getName() ); という記述がありgetName()の結果はPersonクラスのgetName()が表示されるとなっていました。 同様のことをJavaにて試してみたところ Parent pc = new Children(); → ChildrenはParentのサブクラス pc.getName(); getName()にはChildrenクラスのgetName()が表示されました。 C#とJavaでは継承の挙動に違いがあるのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

ソコの解説をよく読むべし。 C#は public new string getName() { ... } new の有無で挙動が変わります(変えることができます)。

unko347
質問者

お礼

ご回答ありがとうございます。 Javaと同様の動作をさせるためには 親クラスのメソッドにvirtualを付けて継承を許可し、 サブクラスのメソッドにはoverrideすることが必要なの ですね。

その他の回答 (1)

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.2

そのページのコードが示す通り、C# ではメソッドはオーバーライド不可がデフォルトで、オーバーライドするには親クラスで許可を与える必要があります。 一方、Java ではオーバーライド可能で、オーバーライド不可にするには final でそのように制約をかけることになります。 これはどちらが優れているかという事ではなくその言語の仕様としてどちらを選んだかにすぎません。 もっとも、Java ではあるメソッドがオーバーライドされているかどうかがわかりづらいため、オーバーライドしたメソッドには @Override アノテーションを付加することが推奨されています(うっかり名前・引数型を間違ってオーバーライドになっていない場合にエラーを出してくれますしね)。

unko347
質問者

お礼

ご回答ありがとうございます。 Javaと同様の動作をさせるためには 親クラスのメソッドにvirtualを付けて継承を許可し、 サブクラスのメソッドにはoverrideすることが必要なの ですね。

関連するQ&A

  • スーパークラスとサブクラスについて

    Parent pc = new Children(); pc.getName(); 下記、2つのクラスがある状態で上記のようにしてgetName()を実行したところ サブクラスのgetName()が呼ばれました。このことからpcオブジェクトの実態はChildrenクラス なのだと理解していたのですが、サブクラスにしか存在しないメソッドを呼ぼうとして pc.getChildName()と記述したところコンパイルエラーになってしまいました。 pc.getParentName()となら記述することができるのですがpcオブジェクトのをどう理解すれば よいのでしょうか。 【親クラス】 public class Parent { public void getName() { System.out.println("Parent"); } public void getParentName() { System.out.println("親クラス特有のメソッド"); } } 【サブクラス】 public class Children extends Parent{ @Override public void getName() { System.out.println("Children"); } public void getChildName() { System.out.println("サブクラス特有のメソッド"); } }

    • ベストアンサー
    • Java
  • javaの継承について

    以下のコードがある場合に、想定では「child」が出力されるとおもっていたのですが、 実際は「parent」が出力されます。 3行目でChildをnewしているので16行目のメソッドが呼び出され 画面に「child」が出力されると思っていたのですが、実行結果で その考えが違う事がわかりました。 実行結果から想定すると、3行目で定義している変数sは Parentクラスを指しているため、4行目で呼び出されるメソッドは 9行目になるのかなと思っています。 しかし、Parentクラス及びChildクラスのstaticを外すと 実行結果がchildとなります。 何故staticをつけた場合とつけない場合で実行結果が 異なるのでしょうか。 ■以下コード 1:public class samplexx { 2:  public static void main(String[] args){ 3:    Parent s = new Child(); 4:    System.out.println(s.getName()); 5:  } 6:} 7:class Parent{ 8:  public static String name ="parent"; 9:  public static String getName(){ 10:    return name; 11:  } 12:} 13: 14:class Child extends Parent{ 15:  public static String name="child"; 16:  public static String getName(){ 17:    return name; 18:  } 19:}

  • virtual時のoverrideとnewの違い

    C#で、 virtualがない時はnewしか使えませんが、 virtualがある時はoverrideとnewが使えますが、 overrideとnewを使った時の違いがよく分かりません。 例えば、基本クラスに public virtual void show(){  Console.WriteLine("基本クラス"); } というメソッドがあるとして、 派生クラスで、 public override void show(){  Console.WriteLine("派生クラス"); } とすると、 基本クラスのメソッドが上書きされて、 Console.WriteLine("派生クラス"); が実行されますが、 派生クラスで、 public new void show(){  Console.WriteLine("派生クラス"); } とした場合にも、 基本クラスのメソッドが隠匿されて、 Console.WriteLine("派生クラス"); だけが実行されます。 virtual使用時において、 継承メソッドの隠匿(new)と、 継承メソッドの上書き(override)では、 一見、なにも違いがないように見えるのですが、 何か違うのでしょうか。

  • C# 匿名メソッドについて

    http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_05/csharp20_05_02.html 匿名メソッドを勉強しています。 上記のサイトの最初のソースで using System; delegate void MyAction(); class Program { static MyAction CreateMethod() { string message = "Hello! World!"; return delegate() { Console.WriteLine(message); }; } static void Main(string[] args) { MyAction action = CreateMethod(); action(); // 出力:Hello! World! } } このソースに対して、 >>常識的に考えればこのプログラムは動作しないはずである。 >>なぜなら、変数messageはCreateMethodメソッドからリターンした瞬間に消滅するが、 >>匿名メソッドが呼ばれるのはその後だからである。 と書かれていますが、 私にはその不思議さがわかりません。 まず、インスタンスされたクラスは初めにMainを読みに行き、 MyAction action = CreateMethod();でCreateMethod()を実行する。その実行した中でreturn”message”が結果的にされる。 そして、それがactionに代入されるという流れだと思うのですが、なぜ、これが不思議なのでしょうか?

  • [言語C#] string型における参照値の受け渡し

    stringは、参照型に分類されると思います。・・・(1) 【string宣言部抜粋】 public sealed class String : IComparable, ICloneable...... また、参照変数の代入では、オブジェクトの参照値が受け渡されるという認識です。・・・(2) 上記(1)、(2)を踏まえると、次のプログラムの実行結果に納得がいきません。 string aiu = "aiu"; string aiue = aiu; Console.WriteLine(aiue); aiu = "abc"; Console.WriteLine(aiu); Console.WriteLine(aiue); 出力結果---------- aiu abc aiu ------------------ (1)、(2)の考えを取り入れた場合、出力結果は aiu abc abc になるものだと思いましたが、なぜこのような結果になるのでしょうか 。自作クラスで似たような処理を行った場合では、一方の変更が同じインスタンスを代入した他方へも影響することは確認済みです。 ただ、stringの場合では・・・違うみたいです。 初歩的なことだと思いますが、宜しくお願い致します。

  • C# override

    某C#の入門書のサンプルですが、overrideがよくわかりません。 using System; using System.Collections.Generic; using System.Text; namespace PersonList {   class Person   {     public string name;     public int age;     public Person(string nam, int ag)     {       name = nam;       age = ag;     }     public override string ToString()     {       return String.Format("{0}({1})", name, age);     }   }   class Program   {     static void Main(string[] args)     {       List<Person> p = new List<Person>();       p.Add(new Person("Pochi", 3));       p.Add(new Person("Kenta", 5));       p.Add(new Person("Mari", 4));       p.Add(new Person("Wanko", 1));       p.Add(new Person("Doggy", 4));       p.ForEach(Console.WriteLine);     }   } } 1.overrideをしないと 「PersonList.Person」が出力されてしまうのですが  なぜToString()をoverrideするのかがわかりません。 2.override しないですべての内容を出力するためにはどうしたら  いいのでしょうか?

  • c# スレッド間でのデータの共有

    C#でメインプロセスと生成されたスレッド間でデータの共有をさせたいのですがどのようにすればいいのでしょうか。ご教授お願い致します。 ・メインプロセス(A) ・Aから生成されたスレッド(B) 例えば、AとBで変数の値をそれぞれ読み書きさせたい場合 どのようにすればよいのでしょうか。 class TEST { public int flag; // メインプロセス(A) public static void Main() { Thread t = new Thread(new ThreadStart(abc)); t.IsBackground = true; t.Start(); while(ture) { Thread.Sleep(10); Console.WriteLine("A:{0}",flag); } } // Aから生成されたスレッド(B) public void abc() { Console.WriteLine("B:{0}",flag); flag++; } }

  • Java 「参照型の型変換」について

    Java初心者です。 入門書を読んでいたら、「参照型の型変換」を説明している項目に 以下の方法で行うと書いてありました。 ==前提=== Personは親クラス Employeeは小クラス Engineerは孫クラス ======== (1)Engineer型からPerson型へ暗黙の型変換する場合 Person per1 = new Engineer(); (2)Person型からEngineer型へキャストする場合 Engineer eng1 = (Engineer) per1; (3)Person型からEmployee型へキャストする場合 Employee emp1 = (Employee) per1; ======== これ、変換の方法は上記で分かったのですが、 そもそも、 "何のために参照型の型変換を行うのか" "型変換を行うと、それぞれのオブジェクトの機能がどのように変わるのか" そういった説明が一切書いておらず、その意味するところが理解出来ませんでした。 スーパークラス型からサブクラス型にキャストする場合、 サブクラス型からスーパークラス型に暗黙の型変換する場合、 それぞれのオブジェクトの性質がどう変化するのでしょうか? メソッドやフィールドに対しての挙動が何か変わるのでしょうか? 基本データ型の型変換は分かり易いんですけどね。。 参照型はどうにも。。 教えて下さい!

    • ベストアンサー
    • Java
  • C# コンストラクタ オーバーロード

    今C#を勉強しているのですが、よくコンストラクタがわかりません。初期化をする、というのは理解できるのですが、オーバーロードの際、 int get; string get2;    Person(int a )   { get=a; get2="ああ" } Person(int b,string a)   { get=b; get2=a } show() { Console.WriteLine("{0}{1}"get,get2); } メインメソッド Person p1 = new Person( 1); Person p2 = new Person(2,"あ"); p1.show(); p2.show(); こうすると出力結果が 1ああ 2あ になるはずですが、(わかりずらいですが、)自分の中ではnew演算子が呼ばれたときにが呼ばれて、変数に値が入ります。そして次のnew演算子でが呼ばれて値が上書きされるので2あ 2あ になると思うのですが。それともp1.show();の時点でもう一回コンストラクタが呼ばれているのでしょうか。要は上書きされるのか、showの時にコンストラクタが呼ばれ、その値で出力されるのか、です。

  • javaのEclipseの問題がわからない

    Human.javaで記述されたクラスを継承し、継承したクラスをインスタンス化して、利用できるHumanクラスのメンバをすべて使用するプログラムを作成せよ。クラス名は、継承したクラスをPerson とし、そのクラスをインスタンス化するクラスをQuestion13_1として、実行結果も記述すること public class Human { private String name = "デフォルトの名前"; protected int age = 22; public int height = 170; final public int weight = 55; public String GetName(){ return name; } public void setName(String name){ this.name = name; } } 結果何を出せば良いのわかりません。

専門家に質問してみよう