キーワードthis
とsuper
の違いは何ですか?
どちらもクラスrightのコンストラクターにアクセスするために使用されますか?誰でも説明できますか?
この状況を考えてみましょう
_class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void anotherEat() {
super.eat();
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eat();
d.anotherEat();
}
}
_
出力は次のようになります
_animal : eat
dog : eat
animal : eat
_
super.eat()
を呼び出しているため、3行目は「animal:eat」を出力しています。 this.eat()
を呼び出した場合、「dog:eat」と出力されます。
super
は基本クラスのメソッドにアクセスするために使用され、this
は現在のクラスのメソッドにアクセスするために使用されます。
概念を拡張し、super()
と書くと、基本クラスのコンストラクターを参照し、this()
と書くと、これを書いているまさにそのクラスのコンストラクターを参照しますコード。
this
は現在のクラスとして入力されたオブジェクトへの参照であり、super
はその親クラスとして入力されたオブジェクトへの参照です。
コンストラクターで、this()
は現在のクラスで定義されたコンストラクターを呼び出します。 super()
は、親クラスで定義されたコンストラクターを呼び出します。コンストラクタは任意の親クラスで定義できますが、現在のクラスに最も近いオーバーライドされたものを参照します。この方法で他のコンストラクターを呼び出すことは、コンストラクターの最初の行としてのみ行うことができます。
メソッドの呼び出しも同じように機能します。 this.method()
を呼び出すと、現在のクラスで定義されているメソッドが呼び出され、super.method()
は親クラスで定義されているのと同じメソッドを呼び出します。
あなたの質問から、あなたは本当にコンストラクタチェーンでのthis
とsuper
の使用について尋ねていると思います。例えば.
public class A extends B {
public A(...) {
this(...);
...
}
}
versus
public class A extends B {
public A(...) {
super(...);
...
}
}
違いは簡単です:
this
フォームは、現在のクラスのコンストラクターにチェーンします。つまり、A
クラスです。
super
フォームは、直接のスーパークラスのコンストラクターにチェーンします。つまり、B
クラスです。
this
はcurrentクラスの参照を参照します。super
は、現在のクラス(super
キーワードと呼ばれる)の親を参照します。
this
を実行すると、現在のクラスのメソッド/属性(独自のプライベートメソッド/属性を含む)にアクセスできます。
super
を使用すると、parent(base)クラスのpublic/protectedメソッド/属性にアクセスできます。親のプライベートメソッド/属性は表示できません。
注:
Super()とthis()はコンストラクタでのみ使用でき、他の場所では使用できません。使用しようとすると、コンパイル時エラーが発生します。
Super()またはthis()をコンストラクターの最初の行として保持する必要がありますが、両方を同時に保持する必要はありません。
注:静的領域(静的ブロックまたはメソッド)を除くクラス内のどこでも両方を使用できます。そうすると、コンパイル時エラーが発生します。
this
は、現在のオブジェクトのメソッドとフィールドにアクセスするために使用されます。このため、たとえば静的メソッドでは意味がありません。
super
は、スーパークラスのプライベートではないメソッドとフィールドへのアクセス、およびクラスのコンストラクター内からのみコンストラクターへのアクセスを許可します。
コードを書くとき、一般的に自分自身を繰り返したくありません。さまざまな数のパラメーターを使用して構築できるクラスがある場合、繰り返しを避けるための一般的な解決策は、欠落している引数にデフォルトを指定して別のコンストラクターを呼び出すことです。これには迷惑な制限が1つだけあります-宣言されたコンストラクタの最初の行でなければなりません。例:
_MyClass()
{
this(default1, default2);
}
MyClass(arg1, arg2)
{
validate arguments, etc...
note that your validation logic is only written once now
}
_
super()
コンストラクタについては、super.method()
アクセスとは異なり、コンストラクタの最初の行である必要があります。その後、this()
コンストラクター、DRY(Do n't Repeat Yourself))に非常に似ています。拡張するクラスに必要な処理を行うコンストラクターがある場合次に、それを使用してから、オブジェクトの構築を続けます。例:
_YourClass extends MyClass
{
YourClass(arg1, arg2, arg3)
{
super(arg1, arg2) // calls MyClass(arg1, arg2)
validate and process arg3...
}
}
_
追加情報:
表示されていなくても、デフォルトの引数なしコンストラクタは常に最初にsuper()
を呼び出します。例:
_MyClass()
{
}
_
と同等です
_MyClass()
{
super();
}
_
メソッドと変数でthis
およびsuper
キーワードを使用することについて多くの人が言及していることがわかります。コンストラクターの使用法には固有の制限があることを覚えておいてください。最も注目すべきは、コンストラクターが宣言されたコンストラクターの最初の命令でなければならず、使用できるのは1つだけであることです。
thisキーワードは、同じクラスのコンストラクターを呼び出すために使用します(他のオーバーロードされたコンストラクター)
syntax:this(args list); //同じクラスの他のコンストラクタのargs listと互換性があります
superキーワードは、スーパークラスのコンストラクターを呼び出すために使用します。
syntax:super(引数リスト); //スーパークラスのコンストラクターのargs listと互換性があります。
例:
public class Rect {
int x1, y1, x2, y2;
public Rect(int x1, int y1, int x2, int y2) // 1st constructor
{ ....//code to build a rectangle }
}
public Rect () { // 2nd constructor
this (0,0,width,height) // call 1st constructor (because it has **4 int args**), this is another way to build a rectangle
}
public class DrawableRect extends Rect {
public DrawableRect (int a1, int b1, int a2, int b2) {
super (a1,b1,a2,b2) // call super class constructor (Rect class)
}
}