Java: 재정의된 메서드를 호출하는 슈퍼 메서드를 호출합니다.
public class SuperClass
{
public void method1()
{
System.out.println("superclass method1");
this.method2();
}
public void method2()
{
System.out.println("superclass method2");
}
}
public class SubClass extends SuperClass
{
@Override
public void method1()
{
System.out.println("subclass method1");
super.method1();
}
@Override
public void method2()
{
System.out.println("subclass method2");
}
}
public class Demo
{
public static void main(String[] args)
{
SubClass mSubClass = new SubClass();
mSubClass.method1();
}
}
예상 출력:
하위 클래스 1 μ μ μ μ μ μ μ μ μ μμ μ μ
초급 방법 1 μ μ μ μ μ μ μ μ μ μ μ μ
슈퍼클래스 메서드2
실제 출력:
하위 클래스 1 μ μ μ μ μ μ μ μ μ μμ μ μ
초급 방법 1 μ μ μ μ μ μ μ μ μ μ μ μ
subclass method2서브클래스 메서드2
엄밀히 말하면 공공의 방식을 무시한 건 알지만 슈퍼에 전화를 걸었기 때문에 슈퍼에 있는 어떤 전화도 슈퍼에 남아있을 거라고 생각했어요. 하지만 이런 일은 일어나지 않아요.어떻게 하면 실현시킬 수 있을까?
키워드 워super
'스틱'이 아니에요!지 는 모든 방법은 개별적으로 처리되므로 든 서 모 별 은 리 에 문 때 " 되 기 you if to is gotually처않개 even콜로으 every적SuperClass.method1()
by calling 부름으로써super
, 그것은 미래에 일어날 수 있는 다른 방법이 없다.향후의 다른 메서드콜에는 영향을 주지 않습니다.
That means there is no direct way to call 즉, 전화를 걸 수 있는 직접적 방법은 없습니다.SuperClass.method2()
부에서SuperClass.method1()
without going though 가지 않고SubClass.method2()
unless you're working with an actual instance of 의 실제 사례를 다루지 않는 한SuperClass
.
Reflection을 사용하여 원하는 효과를 얻을 수도 없습니다( 참조).
[편집] 아직 혼란이 있는 것 같습니다.다른 설명을 해보겠습니다.
를 호출할 때foo()
해서 실제로 발음을 하게 됩니다.this.foo()
를 사용하면 . 를 할 수 .this
에서는 ''입니다this
SubClass
.
가 코드를 할 때SuperClass.method1()
으로는 「」에 this.method2();
「」를 사용합니다.super
에 의해 지적된 예시는 변경되지 않습니다.this
은 '아까보다'로 있습니다SubClass.method2()
this
은 「」입니다.SubClass
.
자바가 '자바'를 하면 이해하기 쉬워요this
" " " " " " "
public class SuperClass
{
public void method1(SuperClass this)
{
System.out.println("superclass method1");
this.method2(this); // <--- this == mSubClass
}
public void method2(SuperClass this)
{
System.out.println("superclass method2");
}
}
public class SubClass extends SuperClass
{
@Override
public void method1(SubClass this)
{
System.out.println("subclass method1");
super.method1(this);
}
@Override
public void method2(SubClass this)
{
System.out.println("subclass method2");
}
}
public class Demo
{
public static void main(String[] args)
{
SubClass mSubClass = new SubClass();
mSubClass.method1(mSubClass);
}
}
스택에 , 「」라고 것을 알 수 .this
않아요, '만들다'에 항상 에서 생성된 인스턴스입니다.main()
.
덮어쓰기 메서드(또는 덮어쓰기 클래스의 다른 메서드)에서만 액세스할 수 있습니다.
""를 덮어쓰지 : ""를 덮어쓰지 마십시오method2()
""를 호출합니다.super.method2()
덮어쓰기 버전 내.
나는 이렇게 생각한다.
+----------------+
| super |
+----------------+ <-----------------+
| +------------+ | |
| | this | | <-+ |
| +------------+ | | |
| | @method1() | | | |
| | @method2() | | | |
| +------------+ | | |
| method4() | | |
| method5() | | |
+----------------+ | |
We instantiate that class, not that one!
그 서브클래스를 왼쪽으로 조금 움직여서 아래가... (아스키 그래픽이 너무 좋아)
We are here
|
/ +----------------+
| | super |
v +----------------+
+------------+ |
| this | |
+------------+ |
| @method1() | method1() |
| @method2() | method2() |
+------------+ method3() |
| method4() |
| method5() |
+----------------+
Then we call the method
over here...
| +----------------+
_____/ | super |
/ +----------------+
| +------------+ | bar() |
| | this | | foo() |
| +------------+ | method0() |
+-> | @method1() |--->| method1() | <------------------------------+
| @method2() | ^ | method2() | |
+------------+ | | method3() | |
| | method4() | |
| | method5() | |
| +----------------+ |
\______________________________________ |
\ |
| |
...which calls super, thus calling the super's method1() here, so that that
method (the overidden one) is executed instead[of the overriding one].
Keep in mind that, in the inheritance hierarchy, since the instantiated
class is the sub one, for methods called via super.something() everything
is the same except for one thing (two, actually): "this" means "the only
this we have" (a pointer to the class we have instantiated, the
subclass), even when java syntax allows us to omit "this" (most of the
time); "super", though, is polymorphism-aware and always refers to the
superclass of the class (instantiated or not) that we're actually
executing code from ("this" is about objects [and can't be used in a
static context], super is about classes).
즉, Java Language Specification에서 인용한 내용은 다음과 같습니다.
»
super.Identifier
이름은 이름이에요.Identifier
현재 객체가 현재 클래스의 슈퍼클래스의 인스턴스로 표시되는 경우.»
T.super.Identifier
이름은 이름이에요.Identifier
" Enclosing instance"에 하는 사전 중T
, 그 를 ,의이이 , , , , , , , , , , , , , , , , , , , , , , , ,.T
.
this
내에서 할 수 있는 ), , (***)입니다.super
실행하려는 코드 블록에 대한 포인터와 같은 단순한 함수 호출에 가깝고 호출되는 클래스에 상대적입니다.
, 「」를 사용하고 는,super
gupper]에서 되지만, 'the gupper class [the grant]에서 'the gupper class]를 this
(암묵적으로 사용되는 경우) 슈퍼클래스에서 계속 서브클래스를 가리키고 있습니다(아무도 변경할 수 없고 아무도 변경할 수 없기 때문입니다).
은 지금 this
객체의 인 인스턴스를 나타냅니다. "사용 중인 "를 합니다.this.method2();
클래스에서는입니다.Method2()는 SubClass입니다.
superClass.method1이 subClass.method2를 호출하지 않도록 method2를 private로 하여 덮어쓸 수 없도록 합니다.
다음은 제안입니다.
public class SuperClass {
public void method1() {
System.out.println("superclass method1");
this.internalMethod2();
}
public void method2() {
// this method can be overridden.
// It can still be invoked by a childclass using super
internalMethod2();
}
private void internalMethod2() {
// this one cannot. Call this one if you want to be sure to use
// this implementation.
System.out.println("superclass method2");
}
}
public class SubClass extends SuperClass {
@Override
public void method1() {
System.out.println("subclass method1");
super.method1();
}
@Override
public void method2() {
System.out.println("subclass method2");
}
}
만약 이것이 이런 방식으로 작용하지 않는다면, 다형성은 불가능할 것이다.
class SuperClass
{
public void method1()
{
System.out.println("superclass method1");
SuperClass se=new SuperClass();
se.method2();
}
public void method2()
{
System.out.println("superclass method2");
}
}
class SubClass extends SuperClass
{
@Override
public void method1()
{
System.out.println("subclass method1");
super.method1();
}
@Override
public void method2()
{
System.out.println("subclass method2");
}
}
부르기
SubClass mSubClass = new SubClass();
mSubClass.method1();
출력
은 method1입니다.
은 superclass method1
2는 superclass method2
메서드를 오버라이드하지 않는 유일한 방법은 키워드 super를 사용하는 것이기 때문에 method2()를 SuperClass에서 다른 새로운 Base 클래스로 이동한 후 SuperClass에서 호출하는 방법을 생각해 보았습니다.
class Base
{
public void method2()
{
System.out.println("superclass method2");
}
}
class SuperClass extends Base
{
public void method1()
{
System.out.println("superclass method1");
super.method2();
}
}
class SubClass extends SuperClass
{
@Override
public void method1()
{
System.out.println("subclass method1");
super.method1();
}
@Override
public void method2()
{
System.out.println("subclass method2");
}
}
public class Demo
{
public static void main(String[] args)
{
SubClass mSubClass = new SubClass();
mSubClass.method1();
}
}
출력:
subclass method1
superclass method1
superclass method2
this
는 항상 현재 실행 중인 개체를 나타냅니다.
요점을 더 자세히 설명하기 위해 간단한 스케치를 제시합니다.
+----------------+
| Subclass |
|----------------|
| @method1() |
| @method2() |
| |
| +------------+ |
| | Superclass | |
| |------------| |
| | method1() | |
| | method2() | |
| +------------+ |
+----------------+
가 있는 는, 「」를 해 주세요.Subclass
내 에서든, """, "", "", """로Superclass
area box의
이 의 클래스 중되지 않기 에, 3개의 클래스 중 1개의 오브젝트가 작성됩니다.this
한 할 수 '이렇게 하다'입니다.을 사용하다
넷빈즈 '히프 워커'에서 보듯이요.
당신이 직접 할 수 있다고 생각하지 않아요.회피책 중 하나는 슈퍼클래스에 method2를 프라이빗 내부 실장하고 그것을 호출하는 것입니다.예를 들어 다음과 같습니다.
public class SuperClass
{
public void method1()
{
System.out.println("superclass method1");
this.internalMethod2();
}
public void method2()
{
this.internalMethod2();
}
private void internalMethod2()
{
System.out.println("superclass method2");
}
}
"this" 키워드는 현재 클래스 참조를 나타냅니다.즉, 메서드 내에서 사용되는 경우 'current' 클래스는 여전히 SubClass이므로 이에 대한 답이 설명됩니다.
요약하자면, 이는 현재 객체를 가리키며 Java에서의 메서드 호출은 본질적으로 다형적입니다.따라서 실행 방법 선택은 이 객체가 가리키는 객체에 전적으로 의존합니다.따라서 부모 클래스에서 method2()를 호출하면 자녀 클래스의 method2()가 호출됩니다.이는 자녀 클래스의 개체를 가리키기 때문입니다.어떤 클래스를 사용하든 정의는 변경되지 않습니다.
추신. 메서드와 달리 클래스의 멤버 변수는 다형이 아닙니다.
같은 케이스의 조사에서는, 콜의 발신지를 특정하기 위해서, 서브 클래스 메서드의 스택트레이스를 체크하고 있었습니다.아마도 더 현명한 방법이 있을 것입니다만, 저는 이 방법이 효과적이고 역동적인 접근 방식입니다.
public void method2(){
Exception ex=new Exception();
StackTraceElement[] ste=ex.getStackTrace();
if(ste[1].getClassName().equals(this.getClass().getSuperclass().getName())){
super.method2();
}
else{
//subclass method2 code
}
}
나는 그 사건에 대한 해결책을 찾기 위한 질문이 타당하다고 생각한다.물론 스레드에서 이미 언급한 바와 같이 다른 메서드 이름이나 다른 파라미터 유형으로 문제를 해결하는 방법도 있지만, 저 같은 경우에는 다른 메서드 이름으로 혼동하고 싶지 않습니다.
또한 제기된 질문의 출력을 확장하면 액세스 지정자 및 덮어쓰기 동작에 대한 자세한 정보를 얻을 수 있습니다.
package overridefunction;
public class SuperClass
{
public void method1()
{
System.out.println("superclass method1");
this.method2();
this.method3();
this.method4();
this.method5();
}
public void method2()
{
System.out.println("superclass method2");
}
private void method3()
{
System.out.println("superclass method3");
}
protected void method4()
{
System.out.println("superclass method4");
}
void method5()
{
System.out.println("superclass method5");
}
}
package overridefunction;
public class SubClass extends SuperClass
{
@Override
public void method1()
{
System.out.println("subclass method1");
super.method1();
}
@Override
public void method2()
{
System.out.println("subclass method2");
}
// @Override
private void method3()
{
System.out.println("subclass method3");
}
@Override
protected void method4()
{
System.out.println("subclass method4");
}
@Override
void method5()
{
System.out.println("subclass method5");
}
}
package overridefunction;
public class Demo
{
public static void main(String[] args)
{
SubClass mSubClass = new SubClass();
mSubClass.method1();
}
}
subclass method1
superclass method1
subclass method2
superclass method3
subclass method4
subclass method5
언급URL : https://stackoverflow.com/questions/4595512/java-calling-a-super-method-which-calls-an-overridden-method
'programing' 카테고리의 다른 글
PHP 오류: 치명적인 오류: 상수 식에 잘못된 작업이 포함되어 있습니다. (0) | 2023.01.02 |
---|---|
PHP로 외부 루프를 끊으려면 어떻게 해야 하나요? (0) | 2022.11.08 |
Python에서 고정 크기의 배열 초기화 (0) | 2022.11.08 |
Jai와 Jai-imageio는 어디서 다운로드 받을 수 있나요? (0) | 2022.11.08 |
이전 인증을 사용하여 MySQL 4.1+에 연결할 수 없음 (0) | 2022.11.08 |