up:: Csharp
up:: Programming

メソッド置き換え

new

C#ではnewはインスタンスを作るだけのものではない。
newを使って メソッドを置き換えられる。 ただし…

namespace Consoleapp5
{
	using System;
	public class Person
	{
		public string getName()
		{
			return "私には名前がありません。"
		}
	}
	
	public class Taro : Person
	{
		public new string getName()
		{
			return "私の名前は太郎です。"
		}
	}
	
	public class Class1
	{
		public static int main(string args[])
		{
			Person person = new Person();
			Console.Writeline(person.getName());
			//私には名前がありません。
			
			Taro taro = new Taro();
			Console.WriteLine(taro.getName());
			//私の名前は太郎です。
			
			Person someone = new Taro();
			Console.WriteLine(someone.getName());
			//私には名前がありません。
			
			return 0;
		}
	}
}

Taroでメソッドの型を決める前にnewを書き、 同名のメソッドを定義してPersonのメソッドを置き換えている。というか書かないと置き換えられない。そのため、Taro型のtaroではしっかり置き換えられている。

しかし、Person型のsomeoneにTaroのインスタンスを突っ込むと、TaroではなくPersonのメソッドを参照してしまう。

つまり、newによる置き換えはデータ型に依存する。
だから早いんだけど。

それでもクラスによって置き換えたいメソッドがある場合は、virtualoverrideを使う。

virtualとoverride

抽象クラス

インターフェース

まとめ

抽象クラスインターフェース
抽象メソッドサブクラスで必ず実装抽象メソッドのみ記述 (自動でpublic abstract)
実装を持つメソッド実装可能実装不可(抽象メソッドのみ) (Java8以降、defaultを使って実装可)
メンバ変数クラスのメンバ変数と同じ必ず定数(自動でpublic static final)
多重継承不可(単一継承のみ)可能

応用

インターフェースでほしいメソッドを定める。
抽象クラスでインターフェースのメソッドを作り、そこに渡す引数が持つメソッドを抽象メソッドとして定める。
これを継承することで、インターフェースが欲したメソッドの中身をある程度まで抽象クラスで作りこみ、それに必要な部品は抽象クラスを継承した子クラスの抽象メソッドの中身を詰めることで作れる。
早い話が、共通部分を抽象クラス内で共通化できる。

ちなみにインターフェースのインスタンスを手動で作ると、インターフェースに紐づいている子クラスの持つメソッドを一気に呼び出せたりもする。

インターフェースと抽象クラスの使い分け、活用方法 - Qiita
【納得Java】抽象クラス(abstract)を使うメリット | 侍エンジニアブログ
↑“Java”なので注意
【C#】インターフェースって何?基礎からしっかり解説してみた! | 侍エンジニアブログ
【詳解】抽象クラスとインタフェースを使いこなそう!! - Qiita