나만의 Android 사용자 지정 클래스를 만들 때 extend
기본 클래스입니다. 나는 기본 메서드를 재정의 할 때 다음, 나는 항상 전화 super()
난 항상에서 할 것처럼, 방법 onCreate
, onStop
등
처음부터 Android 팀이 항상 super
모든 메서드 재정의를 호출하라고 조언했기 때문에 이것이 바로 이것이라고 생각했습니다 .
그러나 많은 책에서 나보다 경험이 많은 개발자들이 종종 전화를 생략하는 super
것을 볼 수 있으며 그들이 지식 부족으로 그렇게하는 것은 정말로 의심 스럽다. 예를 들어 , and 에서 생략 된 기본 SAX 파서 클래스를 살펴보십시오 .super
startElement
characters
endElement
public class SAXParser extends DefaultHandler{
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
//do something
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}else () {
//do something
}
}
}
Eclipse 또는 다른 IDE를 통해 재정의 메서드를 만들려고 super
하면 항상 자동화 된 프로세스의 일부로 만들어집니다.
이것은 단순한 예일뿐입니다. 책은 비슷한 코드 로 가득 차 있습니다 .
언제 전화해야하는지, 언제 전화 super
를 생략 할 수 있는지 어떻게 알 수 있습니까?
추신. 이 특정 예에 바인딩하지 마십시오. 많은 예에서 무작위로 뽑은 예일뿐입니다.
(초보자 질문처럼 들릴 수 있지만 정말 혼란 스럽습니다.)
답변
super
메서드 를 호출하면 메서드 의 동작을 재정의 하는 것이 아니라 확장 하는 것입니다.
에 대한 호출 super
은 확장중인 클래스가 해당 메서드에 대해 정의한 모든 논리를 수행합니다. super
메서드 재정의에서의 구현 을 호출하는 순간이 중요 할 수 있다는 점을 고려 하세요. 예를 들면 :
public class A {
public void save() {
// Perform save logic
}
}
public class B extends A {
private Object b;
@Override
public void save() {
super.save(); // Performs the save logic for A
save(b); // Perform additional save logic
}
}
에 대한 호출 은 및에 B.save()
대한 save()
논리를 이 특정 순서로 수행합니다. 당신이 호출되지 않은 경우 내부 , 호출 할 수 없습니다 것입니다. 당신이라고한다면 후 , 효과적으로 이후에 수행 될 것이다 .A
B
super.save()
B.save()
A.save()
super.save()
save(b)
A.save()
B.save()
의 동작 을 재정의 하려는 경우 super
(즉, 구현을 완전히 무시하고 모두 직접 제공)을 호출해서는 안됩니다 super
.
SAXParser
제공 하는 예제 에서 해당 메서드 에 대한 구현 은 DefaultHandler
비어 있으므로 하위 클래스가 해당 메서드를 재정의하고 해당 메서드에 대한 동작을 제공 할 수 있습니다. 이 메소드에 대한 javadoc 에서 이것도 지적됩니다.
public void startElement (String uri, String localName,
String qName, Attributes attributes) throws SAXException {
// no op
}
그의 주석에서 지적했듯이 super()
IDE에 의해 생성 된 코드 의 기본 호출에 @barsju
대해서는 각 생성자에 암시 적 호출이 있습니다 super()
(코드에 작성하지 않더라도). 즉, 해당 컨텍스트에서 super
‘ s 기본 생성자. 는 IDE
당신을 위해 그것을 적어 놓았지만 당신이 그것을 제거하면 호출 될 것입니다. 또한 생성자를 구현할 때 super()
또는 인수가있는 변형 (예 🙂 은 메서드 의 맨 처음super(x,y,z)
에만 호출 할 수 있습니다 .
답변
언제 super에 전화해야하는지, 언제 전화를 생략 할 수 있는지 어떻게 알 수 있습니까?
일반적으로 특별한 API 방법은 기본 프레임 워크 컨텍스트 라이프 사이클에 중요한 의미가있는 경우, 항상 명시 적으로 언급되고처럼, API 문서에서 강조 Activity.onCreate()
API 문서 . 또한 API가 강력한 설계를 따르는 경우 프로젝트 컴파일시 소비자 개발자에게 경고하기 위해 몇 가지 예외를 throw하고 런타임에 오류가 발생하지 않도록해야합니다.
이것이 API 문서에 명시 적으로 명시되지 않은 경우 소비자 개발자는 API 메서드를 재정의 할 때 반드시 호출해야하는 것이 아니라고 가정하는 것이 안전합니다. 기본 동작 ( super
메소드 호출)을 사용할지 또는 완전히 재정의 할지 여부는 소비자 개발자에게 달려 있습니다.
조건이 허용되면 (저는 오픈 소스 소프트웨어를 좋아합니다) 소비자 개발자는 항상 API 소스 코드를 확인하고 메서드가 실제로 어떻게 작성되는지 확인할 수 있습니다. 예를 들어 Activity.onCreate()
소스 와 DefaultHandler.startElement()
소스 를 확인하십시오 .
답변
머릿속에서해야 할 테스트는 다음과 같습니다.
“이 방법의 모든 기능을 수행 한 다음 나중에 작업을 수행해야합니까?” 그렇다면을 호출 super()
한 다음 메서드를 완료합니다. 이는 onDraw()
백그라운드에서 많은 것을 처리하는와 같은 “중요한”메소드 에 해당됩니다.
(재정의 할 대부분의 메서드와 마찬가지로) 일부 기능 만 원하는 경우을 호출하고 싶지 않을 것입니다 super()
.
답변
그럼 사비는 더 나은 대답을했다 …하지만 당신은 아마 무엇을하는지 알 수 있습니다super()
기본 동작으로 수행 한 어떤 오버라이드 (override) 방법 … 그것은 광고에 전화했을 때 어떻게 ..
예 :
onDraw()
재정의되었을 때 뷰 클래스의 메소드 .. super.onDraw ()라고 말하기 전에 무언가를 그립니다. 뷰가 완전히 그려지면 나타납니다. 따라서 super
Android에는 onCreate ()와 같은 매우 중요한 작업이 있기 때문에 여기서 호출 해야합니다.
하지만 동시에
onLongClick()
당신이 이것을 재정의 할 때 당신은 EditText 또는 다른 유사한보기에 대한 옵션 목록이있는 대화 상자를 불러 오기 때문에 super를 호출하고 싶지 않습니다. 그것은 기본적인 차이점입니다 .. 당신은 그것을 몇 번 남겨 두도록 선택할 수 있습니다. onCreate() , onStop()
OS가 처리하도록해야하는 것과 같은 다른 방법 ..
답변
귀하의 질문을 명확하게 이해하지 못했지만 super
메서드를 호출하지 않는 이유에 대해 묻는 경우 :
super
메서드 를 호출하는 이유가 있습니다 . 부모 클래스에 인수가없는 생성자가 없으면 자식 클래스를 만들 수 없으므로 부모 클래스에 인수없는 생성자를 유지해야하거나 자식 클래스 생성자의 맨 위에 super()
호출 문 을 정의 argument(how much argument constructor you have used in super class)
합니다.
이게 도움이 되길 바란다. 그렇지 않다면 알려주세요.
답변
나는 다음과 같은 제약 배열 목록을 구현했다.
public class ConstraintArrayList<T> extends ArrayList<T> {
ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
@Override
public boolean add(T element) {
if (cons.accept(element))
return super.add(element);
return false;
}
}
코드를 살펴보면 실제로 수퍼 클래스가 목록에 요소를 실제로 추가하도록하기 전에 몇 가지 사전 검사를 수행합니다. 이것은 메서드 재정의에 대한 두 가지 이유 중 하나를 알려줍니다.
- 수퍼 클래스가 수행 할 수있는 작업을 확장하려는 확장 성
- 새가 움직이는 (날다) 및 개구리가 움직이는 (홉) 방식이 각 하위 클래스에 고유 한 이동 의미론의 일반적인 동물 왕국 예제에서와 같이 다형성을 통해 특정 동작을 추가하려는 특이성.