Java에서 다중 상속이없는 이유는 있지만 여러 인터페이스를 구현할 수 있습니까?
Java는 다중 상속을 허용하지 않지만 다중 인터페이스를 구현할 수 있습니다. 왜?
인터페이스 만 지정하기 때문에 어떤 클래스가 아니라하고있다 어떻게 그것을하고있다.
다중 상속의 문제점은 두 클래스가 동일한 작업을 수행하는 다른 방법 을 정의 할 수 있으며 서브 클래스는 선택할 방법을 선택할 수 없다는 것입니다.
내 대학 강사 중 한 명이이 방법을 설명했습니다.
토스터 인 클래스 하나와 NuclearBomb 클래스가 있다고 가정 해 봅시다. 둘 다 "어둠"설정이있을 수 있습니다. 둘 다 on () 메소드를 가지고 있습니다. (하나는 off ()를 가지고 있고, 다른 하나는 그렇지 않습니다.) 둘 다의 서브 클래스 인 클래스를 만들려면 여기에서 볼 수 있듯이 이것은 실제로 내 얼굴을 날려 버릴 수있는 문제입니다. .
따라서 주요 문제 중 하나는 부모 클래스가 두 개인 경우 강사의 예에서와 같이 동일한 기능의 다른 구현 또는 동일한 이름을 가진 두 개의 다른 기능을 가질 수 있다는 것입니다. 그런 다음 서브 클래스에서 사용할 클래스를 결정해야합니다. 이를 처리하는 방법은 확실히 있습니다. C ++도 마찬가지입니다. 그러나 Java 설계자들은 이것이 너무 복잡해질 것이라고 생각했습니다.
그러나 인터페이스를 사용하면 다른 클래스의 방법을 빌려주는 대신 클래스가 수행 할 수있는 것을 설명합니다. 다중 인터페이스는 다중 상위 클래스보다 해결해야하는 까다로운 충돌을 유발할 가능성이 훨씬 낮습니다.
"이봐, 그 방법은 유용 해 보인다. 나는 그 클래스도 확장 할 것이다"라고 말할 수 없을 때에도 상속이 과도하게 사용되기 때문이다 .
public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter,
AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...
이 질문에 대한 답은 java 컴파일러 (생성자 체인)의 내부 작업에 있습니다. Java 컴파일러의 내부 작업을 보면 :
public class Bank {
public void printBankBalance(){
System.out.println("10k");
}
}
class SBI extends Bank{
public void printBankBalance(){
System.out.println("20k");
}
}
이 컴파일 후 다음과 같습니다
public class Bank {
public Bank(){
super();
}
public void printBankBalance(){
System.out.println("10k");
}
}
class SBI extends Bank {
SBI(){
super();
}
public void printBankBalance(){
System.out.println("20k");
}
}
클래스를 확장하고 그 객체를 만들면 클래스 하나까지 생성자 체인 하나가 실행됩니다 Object
.
위의 코드는 정상적으로 실행됩니다. 그러나 Car
확장 이라는 다른 클래스 Bank
와 하나의 하이브리드 (다중 상속) 클래스 가 있다면 SBICar
:
class Car extends Bank {
Car() {
super();
}
public void run(){
System.out.println("99Km/h");
}
}
class SBICar extends Bank, Car {
SBICar() {
super(); //NOTE: compile time ambiguity.
}
public void run() {
System.out.println("99Km/h");
}
public void printBankBalance(){
System.out.println("20k");
}
}
이 경우 (SBICar)는 생성자 체인을 생성하지 못합니다 ( 컴파일 시간 모호성 ).
인터페이스의 경우 객체를 만들 수 없으므로 허용됩니다.
새로운 개념 default
과 static
방법 에 대해서는 인터페이스에서 기본값을 참조하십시오 .
이것이 쿼리를 해결할 수 있기를 바랍니다. 감사.
여러 인터페이스를 구현하는 것은 매우 유용하며 언어 구현 자나 프로그래머에게 많은 문제를 일으키지 않습니다. 따라서 허용됩니다. 다중 상속도 유용하지만 사용자에게 심각한 문제를 일으킬 수 있습니다 ( 사망의 다이아몬드 ). 그리고 다중 상속으로 수행하는 대부분의 작업은 구성 또는 내부 클래스를 사용하여 수행 할 수도 있습니다. 따라서 여러 상속은 이익보다 더 많은 문제를 일으키는 것으로 금지됩니다.
Java는 인터페이스를 통해서만 다중 상속을 지원합니다. 클래스는 여러 인터페이스를 구현할 수 있지만 하나의 클래스 만 확장 할 수 있습니다.
다중 상속은 치명적인 다이아몬드 문제로 이어지기 때문에 지원되지 않습니다. 그러나 해결할 수는 있지만 복잡한 시스템으로 이어 지므로 Java 설립자가 다중 상속을 중단했습니다.
1995 년 2 월 James Gosling의“Java : Overview”백서 ( link )에서는 Java에서 다중 상속이 지원되지 않는 이유에 대한 아이디어를 제공합니다.
고슬링에 따르면 :
"JAVA는 C ++의 거의 사용되지 않고 이해하기 어려운 혼란스러운 기능을 많이 사용하지 않아 경험에 비해 더 많은 슬픔을 겪습니다. 이는 주로 연산자 오버로드 (메소드 오버로드가 있지만), 다중 상속 및 광범위한 자동 강제로 구성됩니다."
같은 이유로 C #은 다중 상속을 허용하지 않지만 다중 인터페이스를 구현할 수 있습니다.
다중 상속을 통한 C ++에서 얻은 교훈은 가치보다 더 많은 문제가 발생한다는 것입니다.
An interface is a contract of things your class has to implement. You don't gain any functionality from the interface. Inheritence allows you to inherit the functionality of a parent class (and in multiple-inheritence, that can get extremely confusing).
Allowing multiple interfaces allows you to use Design Patterns (like Adapter) to solve the same types of issues you can solve using multiple inheritence, but in a much more reliable and predictable manner.
You can find accurate answer for this query in oracle documentation page about multiple inheritance
Multiple inheritance of state: Ability to inherit fields from multiple classes
One reason why the Java programming language does not permit you to extend more than one class is to avoid the issues of multiple inheritance of state, which is the ability to inherit fields from multiple classes
If multiple inheritance is allowed and When you create an object by instantiating that class, that object will inherit fields from all of the class's superclasses. It will cause two issues.
- What if methods or constructors from different super classes instantiate the same field?
- Which method or constructor will take precedence?
Multiple inheritance of implementation: Ability to inherit method definitions from multiple classes
Problems with this approach: name conflicts and ambiguity. If a subclass and superclass contain same method name (and signature), compiler can't determine which version to invoke.
But java supports this type of multiple inheritance with default methods, which have been introduced since Java 8 release. The Java compiler provides some rules to determine which default method a particular class uses.
Refer to below SE post for more details on resolving diamond problem:
What are the differences between abstract classes and interfaces in Java 8?
Multiple inheritance of type: Ability of a class to implement more than one interface.
Since interface does not contain mutable fields, you do not have to worry about problems that result from multiple inheritance of state here.
It is said that objects state is referred with respect to the fields in it and it would become ambiguous if too many classes were inherited. Here is the link
http://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html
Since this topic is not close I'll post this answer, I hope this helps someone to understand why java does not allow multiple inheritance.
Consider the following class:
public class Abc{
public void doSomething(){
}
}
In this case the class Abc does not extends nothing right? Not so fast, this class implicit extends the class Object, base class that allow everything work in java. Everything is an object.
If you try to use the class above you'll see that your IDE allow you to use methods like: equals(Object o)
, toString()
, etc, but you didn't declare those methods, they came from the base class Object
You could try:
public class Abc extends String{
public void doSomething(){
}
}
This is fine, because your class will not implicit extends Object
but will extends String
because you said it. Consider the following change:
public class Abc{
public void doSomething(){
}
@Override
public String toString(){
return "hello";
}
}
Now your class will always return "hello" if you call toString().
Now imagine the following class:
public class Flyer{
public void makeFly(){
}
}
public class Bird extends Abc, Flyer{
public void doAnotherThing(){
}
}
Again class Flyer
implicit extends Object which has the method toString()
, any class will have this method since they all extends Object
indirectly, so, if you call toString()
from Bird
, which toString()
java would have to use? From Abc
or Flyer
? This will happen with any class that try to extends two or more classes, to avoid this kind of "method collision" they built the idea of interface, basically you could think them as an abstract class that does not extends Object indirectly. Since they are abstract they will have to be implemented by a class, which is an object (you cannot instanciate an interface alone, they must be implemented by a class), so everything will continue to work fine.
To differ classes from interfaces, the keyword implements was reserved just for interfaces.
You could implement any interface you like in the same class since they does not extends anything by default (but you could create a interface that extends another interface, but again, the "father" interface would not extends Object"), so an interface is just an interface and they will not suffer from "methods signature colissions", if they do the compiler will throw a warning to you and you will just have to change the method signature to fix it (signature = method name + params + return type).
public interface Flyer{
public void makeFly(); // <- method without implementation
}
public class Bird extends Abc implements Flyer{
public void doAnotherThing(){
}
@Override
public void makeFly(){ // <- implementation of Flyer interface
}
// Flyer does not have toString() method or any method from class Object,
// no method signature collision will happen here
}
Because an interface is just a contract. And a class is actually a container for data.
For example two class A,B having same method m1(). And class C extends both A, B.
class C extends A, B // for explaining purpose.
Now, class C will search the definition of m1. First, it will search in class if it didn't find then it will check to parents class. Both A, B having the definition So here ambiguity occur which definition should choose. So JAVA DOESN'T SUPPORT MULTIPLE INHERITANCE.
Java does not support multiple inheritance because of two reasons:
- In java, every class is a child of
Object
class. When it inherits from more than one super class, sub class gets the ambiguity to acquire the property of Object class.. - In java every class has a constructor, if we write it explicitly or not at all. The first statement is calling
super()
to invoke the supper class constructor. If the class has more than one super class, it gets confused.
So when one class extends from more than one super class, we get compile time error.
Take for example the case where Class A has a getSomething method and class B has a getSomething method and class C extends A and B. What would happen if someone called C.getSomething? There is no way to determine which method to call.
Interfaces basically just specify what methods a implementing class needs to contain. A class that implements multiple interfaces just means that class has to implement the methods from all those interfaces. Whci would not lead to any issues as described above.
Consider a scenario where Test1, Test2 and Test3 are three classes. The Test3 class inherits Test2 and Test1 classes. If Test1 and Test2 classes have same method and you call it from child class object, there will be ambiguity to call method of Test1 or Test2 class but there is no such ambiguity for interface as in interface no implementation is there.
Java does not support multiple inheritance , multipath and hybrid inheritance because of ambiguity problem:
Scenario for multiple inheritance: Let us take class A , class B , class C. class A has alphabet(); method , class B has also alphabet(); method. Now class C extends A, B and we are creating object to the subclass i.e., class C , so C ob = new C(); Then if you want call those methods ob.alphabet(); which class method takes ? is class A method or class B method ? So in the JVM level ambiguity problem occurred. Thus Java does not support multiple inheritance.
Reference Link: https://plus.google.com/u/0/communities/102217496457095083679
in simple manner we all know, we can inherit(extends) one class but we can implements so many interfaces.. that is because in interfaces we don't give an implementation just say the functionality. suppose if java can extends so many classes and those have same methods.. in this point if we try to invoke super class method in the sub class what method suppose to run??, compiler get confused example:- try to multiple extends but in interfaces those methods don't have bodies we should implement those in sub class.. try to multiple implements so no worries..
* This is a simple answer since I'm a beginner in Java *
Consider there are three classes X
,Y
and Z
.
So we are inheriting like X extends Y, Z
And both Y
and Z
is having a method alphabet()
with same return type and arguments. This method alphabet()
in Y
says to display first alphabet and method alphabet in Z
says display last alphabet. So here comes ambiguity when alphabet()
is called by X
. Whether it says to display first or last alphabet??? So java is not supporting multiple inheritance. In case of Interfaces, consider Y
and Z
as interfaces. So both will contain the declaration of method alphabet()
but not the definition. It won't tell whether to display first alphabet or last alphabet or anything but just will declare a method alphabet()
. So there is no reason to raise the ambiguity. We can define the method with anything we want inside class X
.
So in a word, in Interfaces definition is done after implementation so no confusion.
'Programing' 카테고리의 다른 글
부모 행을 삭제하거나 업데이트 할 수 없습니다. 외래 키 제약 조건이 실패합니다 (0) | 2020.06.17 |
---|---|
AllowOverride all을 설정하는 방법 (0) | 2020.06.17 |
UIViewContentModeScaleAspectFill이 클리핑되지 않음 (0) | 2020.06.16 |
동결과 밀봉의 차이점 (0) | 2020.06.16 |
onCreate ()와 onStart ()의 차이점은 무엇입니까? (0) | 2020.06.16 |