override
「override」とは・「override」の意味
「override」とは、ある機能や動作を上書きして、別の機能や動作に置き換えることを意味する。プログラミングの分野では、親クラスのメソッドを子クラスで再定義することを指す。これにより、親クラスのメソッドを継承しつつ、子クラスで独自の処理を実装することが可能となる。「override」の発音・読み方
「override」の発音は、オーバーライドと読む。アクセントは「オーバー」の部分に置かれる。「override」の語源・由来
「override」は英語で、「over」(上に)と「ride」(乗る)の二つの単語が組み合わさったものである。これは、ある機能や動作が他のものの上に乗って、それを置き換えるという意味合いを持つ。「override」の類語
「override」の類語としては、「overwrite」や「supersede」がある。「overwrite」は、データやファイルを上書きすることを意味し、「supersede」は、古いものを新しいものに置き換えることを指す。「override」を含む用語・関連する用語
「Override(Java)」とは
「Override(Java)」とは、Javaプログラミング言語において、親クラスのメソッドを子クラスで上書きすることを指す。これにより、親クラスのメソッドを継承しつつ、子クラスで独自の処理を実装することができる。「C++ override」とは
「C++ override」とは、C++プログラミング言語において、親クラスのメソッドを子クラスで上書きすることを指す。これにより、親クラスのメソッドを継承しつつ、子クラスで独自の処理を実装することができる。「overrideアノテーション」とは
「overrideアノテーション」とは、Javaプログラミング言語において、親クラスのメソッドを子クラスで上書きする際に使用されるアノテーションである。これにより、コンパイラが上書きが正しく行われているかをチェックすることができる。「override」の使い方・例文
1. The child class overrides the parent class's method.(子クラスが親クラスのメソッドを上書きする)2. The new settings will override the old ones.(新しい設定が古いものを上書きする)
3. The manager has the authority to override the decision.(マネージャーはその決定を上書きする権限がある)
4. The system will automatically override the manual input.(システムは手動入力を自動的に上書きする)
5. The software update will override the previous version.(ソフトウェアのアップデートが前のバージョンを上書きする)
6. The local settings override the global settings.(ローカル設定がグローバル設定を上書きする)
7. The new law overrides the existing regulations.(新しい法律が既存の規制を上書きする)
8. The emergency protocol overrides the standard procedure.(緊急プロトコルが標準手順を上書きする)
9. The user can override the default settings.(ユーザーはデフォルト設定を上書きすることができる)
10. The new policy overrides the previous one.(新しいポリシーが以前のものを上書きする)
オーバーライド
オーバーライド
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/09/25 10:41 UTC 版)
オブジェクト指向プログラミングにおいてオーバーライド (override) とは、スーパークラスで定義されたメソッドをサブクラスで定義し直し、動作を上書き(変更)することである。
例えば、あるクラスBase
にメソッドprint
があり、あるクラスDerived
がクラスBase
を継承したとする。そのとき、クラスDerived
はクラスBase
にあるメソッドprint
をオーバーライドすることにより、再定義することができる。これはオブジェクト指向プログラミングにおけるポリモーフィズム(多態性)を実現する際によく使われる。
通例、オーバーライドを可能とする条件として、メソッドの名前、引数の数と型の順序、そして戻り値の型が統一されている必要がある[注釈 1]。
メソッドのオーバーロード(多重定義、overload)と名前は似ているが、まったく異なる概念である。
Rubyのようにオーバーロードの概念がなく、引数の型や数の条件がなくメソッド名が同一なだけでオーバーライドが成立するプログラミング言語もある。
オーバーライドの例
Java
Javaのインスタンスメソッドは仮想メソッドであり、派生クラスでオーバーライド可能である。インスタンスメソッドを非仮想にする手段はないが、final
キーワードを指定することでオーバーライドを禁止することはできる。
なお、Java SE 5から導入されたアノテーション@Override
を用いることで、メソッドがオーバーライドされていることをコンパイラに知らせることができる(正しくオーバーライドされていない場合、コンパイルエラーとなる)。しかし、アノテーションの指定はオプションであり必須ではない。
// 基本クラス。
class Base {
// コンストラクター
Base() {
System.out.println("Base.Base()");
}
// インスタンスメソッド
void print() {
System.out.println("Base.print()");
}
// クラスメソッド
static void staticPrint() {
System.out.println("Base.staticPrint()");
}
}
// 派生クラス。
class Derived extends Base {
// コンストラクター
Derived() {
System.out.println("Derived.Derived()");
}
// スーパークラスのインスタンスメソッド print をオーバーライドしている。@Override の指定は必須ではないが推奨される。
@Override
void print() {
System.out.println("Derived.print()");
}
// スーパークラスのクラスメソッド staticPrint をオーバーライドすることはできない。隠蔽することになる。
static void staticPrint() {
System.out.println("Derived.staticPrint()");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("■ Baseインスタンスメソッドの呼び出し:");
Base base = new Base();
base.print();
System.out.println("■ Derivedインスタンスメソッドの呼び出し:");
Derived derived = new Derived();
derived.print();
System.out.println("■ Base型変数を経由したDerivedインスタンスメソッドのポリモーフィック呼び出し:");
Base derivedInBaseVariable = new Derived();
derivedInBaseVariable.print();
System.out.println("■ Baseクラスメソッドの呼び出し:");
Base.staticPrint();
System.out.println("■ Derivedクラスメソッドの呼び出し:");
Derived.staticPrint();
}
}
実行結果:
■ Baseインスタンスメソッドの呼び出し:
Base.Base()
Base.print()
■ Derivedインスタンスメソッドの呼び出し:
Base.Base()
Derived.Derived()
Derived.print()
■ Base型変数を経由したDerivedインスタンスメソッドのポリモーフィック呼び出し:
Base.Base()
Derived.Derived()
Derived.print()
■ Baseクラスメソッドの呼び出し:
Base.staticPrint()
■ Derivedクラスメソッドの呼び出し:
Derived.staticPrint()
C#
C#のオーバーライドの特徴として、以下が挙げられる。
- 仮想メソッドおよび抽象メソッドのオーバーライドの際に
override
キーワードの指定が必要である。
- ただし、インターフェイスのメソッドを実装する場合は、
override
の指定は不要 (不可) である。
- メソッドは既定では非仮想であり、
virtual
を指定することでオーバーライド可能な仮想メソッドとなる。 - プロパティ、インデクサ、イベントも、
virtual
修飾されている場合はメソッドと同様にオーバーライドの対象となる。 sealed
キーワードを指定することでオーバーライドを禁止できる。
コードの例を示す。
// 抽象基本クラス。
abstract class Base {
// 既定では非仮想メソッド。
public void GoodMorning() { Console.WriteLine("Good morning, Base!"); }
// virtualを指定することで仮想メソッドとなる。
public virtual void Hello() { Console.WriteLine("Hello, Base!"); }
public virtual void Goodbye() { Console.WriteLine("Goodbye, Base!"); }
// 抽象メソッド(実装を持たない)。
public abstract void GoodNight();
}
// 派生クラス。
class Derived : Base {
// 非仮想メソッドはオーバーライドできない。
// 同名のメソッドで隠蔽する場合、newを指定する。
// (ここでは指定しないが、さらにvirtualを指定することで仮想メソッドとなる)
public new void GoodMorning() { Console.WriteLine("Good morning, Derived!"); }
// 仮想メソッドをオーバーライドする。
// overrideの指定が必須。
public override void Hello() { Console.WriteLine("Hello, Derived!"); }
// 仮想メソッドをオーバーライドする。
// overrideと共にsealedを指定することで、このクラスを継承した先ではオーバーライドが禁止される。
public override sealed void Goodbye() { Console.WriteLine("Goodbye, Derived!"); }
// 抽象メソッドをオーバーライドする。
// overrideの指定が必須。
public override void GoodNight() { Console.WriteLine("Good night, Derived!"); }
}
class DerivedDerived : Derived {
// 非仮想メソッドはオーバーライド不可。
//public override void GoodMorning() { Console.WriteLine("Good morning, DerivedDerived!"); }
public override void Hello() { Console.WriteLine("Hello, DerivedDerived!"); }
// sealedされたメソッドはオーバーライド不可。
//public override void Goodbye() { Console.WriteLine("Goodbye, DerivedDerived!"); }
public override void GoodNight() { Console.WriteLine("Good night, DerivedDerived!"); }
}
言語固有の注意点
あるスーパークラスとそれを継承したサブクラスを定義する際、JavaやC++ではオーバーライドに関係した問題が起こりうるので注意が必要である(特にスーパークラスの実装者とサブクラスの実装者が異なる場合)。Javaのインスタンスメソッドは仮想メソッドであり、あとからスーパークラスにメソッドを追加したときに、そのメソッドと同じシグネチャのメソッドが既にサブクラスに存在すると、オーバーライドしたつもりがないのに関係のないメソッドをオーバーライドしてしまうという問題が起こる。逆にオーバーライドしたつもりでも、スーパークラスのメソッドシグネチャあるいはアクセシビリティの変更[注釈 2]や、サブクラスのメソッド定義時のtypoなどによって正しくオーバーライドできていなかった、といった問題も起こる。後者の問題を回避するためにJavaでは@Override
の指定が推奨されるが、後方互換性を保つため、アノテーションの指定は必須とはなっていない。C++においてもC++11でoverride
修飾子が導入されたが、override
修飾子の指定はオプションであり必須ではない。
// 基底クラス。
class Base {
public Base() {
System.out.println("Base.Base()");
this.init();
}
// アクセス修飾子を変更して、派生クラスから見えるようにすると、
// Derived で意図せずオーバーライドしてしまうことになる。
// 結果として、コンストラクタの振る舞いが変わってしまう。
// 誤ってオーバーライドしてしまうことを防ぐには、final 指定する必要がある。
private void init() {
System.out.println("Base.init()");
}
}
// 派生クラス。
class Derived extends Base {
public Derived() {
System.out.println("Derived.Derived()");
this.init();
}
// もし基底クラスで同名の可視メソッドが定義されている場合、オーバーライドする。
public void init() {
System.out.println("Derived.init()");
}
}
public class Main {
public static void main(String[] args) {
Derived derived = new Derived();
}
}
C#ではメソッドが既定で非仮想であり、またオーバーライドするには当初からoverride
修飾子が必須なのでこの問題は起こらない。基底クラスを変更しても、破壊的な変更につながりにくくなっている。
// 基底クラス。
class Base {
public Base() {
System.Console.WriteLine("Base.Base()");
this.Init();
}
// アクセス修飾子を変更して、派生クラスから見えるようにしても、
// Derived で意図せずオーバーライドしてしまうことにはならない。
// 仮に基底クラスで virtual 指定したとしても、派生クラスで override 指定が必須となるため、
// 意図せずオーバーライドしてしまうことにはならない。
private void Init() {
System.Console.WriteLine("Base.Init()");
}
}
// 派生クラス。
class Derived : Base {
public Derived() {
System.Console.WriteLine("Derived.Derived()");
this.Init();
}
// もし基底クラスで同名の可視メソッドが定義されている場合、隠蔽する。
// new の指定は必須ではないが、new を指定せず隠蔽した場合はコンパイラが警告を出す。
public void Init() {
System.Console.WriteLine("Derived.Init()");
}
}
public class Test {
public static void Main() {
Derived derived = new Derived();
}
}
Kotlin[1]やSwift[2]のような後発言語では、C#同様にオーバーライドにはoverride
の指定が必須となっている。
脚注
注釈
出典
関連項目
オーバーライド
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/03/26 10:17 UTC 版)
「Gatekeeper (macOS)」の記事における「オーバーライド」の解説
Gatekeeperをオーバーライドするには、ユーザ(管理者として機能)は、システム設定のセキュリティとプライバシーパネルからより緩やかなポリシーに切り替えるか、コンテキストメニューからアプリケーションを開く、もしくは、特定のアプリケーションの手動オーバーライドを許可する必要がある。また、spctlで追加することもできる。
※この「オーバーライド」の解説は、「Gatekeeper (macOS)」の解説の一部です。
「オーバーライド」を含む「Gatekeeper (macOS)」の記事については、「Gatekeeper (macOS)」の概要を参照ください。
「オーバーライド」の例文・使い方・用例・文例
固有名詞の分類
- オーバーライドのページへのリンク