ฉันจะทำสิ่งนี้ได้อย่างไร:
public class Main extends ListActivity , ControlMenu
นอกจากนี้ฉันอยากจะรู้ว่าวิธีนี้ก็โอเคที่ฉันได้ทำเมนูในชั้นเรียนซึ่งเป็น ControlMenu และฉันได้ขยายกิจกรรมที่เหลือ
ฉันจะทำสิ่งนี้ได้อย่างไร:
public class Main extends ListActivity , ControlMenu
นอกจากนี้ฉันอยากจะรู้ว่าวิธีนี้ก็โอเคที่ฉันได้ทำเมนูในชั้นเรียนซึ่งเป็น ControlMenu และฉันได้ขยายกิจกรรมที่เหลือ
คำตอบ:
คุณสามารถขยายชั้นเรียนเดียวเท่านั้น และใช้อินเทอร์เฟซจากหลายแหล่ง
ไม่สามารถขยายหลายคลาสได้ ทางออกเดียวที่ฉันนึกได้คือไม่ได้สืบทอดคลาสใดคลาสหนึ่ง แต่มีตัวแปรภายในของแต่ละคลาสและทำพร็อกซีให้มากขึ้นโดยเปลี่ยนทิศทางการร้องขอไปยังวัตถุของคุณไปยังวัตถุที่คุณต้องการให้พวกเขาไป
public class CustomActivity extends Activity {
private AnotherClass mClass;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mClass = new AnotherClass(this);
}
//Implement each method you want to use.
public String getInfoFromOtherClass()
{
return mClass.getInfoFromOtherClass();
}
}
นี่เป็นทางออกที่ดีที่สุดที่ฉันคิดไว้ คุณสามารถรับฟังก์ชั่นการใช้งานจากทั้งคลาสและยังคงเป็นประเภทคลาสเดียวเท่านั้น
ข้อเสียเปรียบคือคุณไม่สามารถบรรจุลงใน Mold of the Internal class โดยใช้การร่าย
ทำไมไม่ใช้ชั้นใน (ทำรัง)
class A extends B {
private class C extends D {
//Classes A , B , C , D accessible here
}
}
Fragmentไม่สามารถรับระดับชั้นในการทำงานใน กิจกรรมของฉันต้องขยายออกไปFragmentซึ่งหมายความว่าฉันต้องการอย่างยิ่งgetView()ซึ่งจะไม่ทำงานถ้ามันอยู่ในชั้นในและรหัสในที่นั่นคือที่ที่ฉันต้องใช้รหัสจากListActivityดังนั้นฉันจึงไม่สามารถขยายได้สองครั้งหรือทำชั้นใน ในตัวอย่างนี้
อย่างที่ทุกคนพูดกัน ไม่คุณไม่สามารถ อย่างไรก็ตามถึงแม้ว่าผู้คนจะพูดหลายครั้งในหลายปีที่ผ่านมาว่าคุณควรใช้อินเทอร์เฟซหลายอย่างที่พวกเขาไม่ได้ทำ หวังว่านี่จะช่วยได้
สมมติว่าคุณมีclass Fooและที่คุณทั้งสองต้องการที่จะลองขยายเป็นclass Bar class FooBarแน่นอนอย่างที่คุณพูดคุณไม่สามารถทำได้:
public class FooBar extends Foo, Bar
ผู้คนได้เข้าไปหาเหตุผลของสิ่งนี้ในระดับหนึ่งแล้ว ให้เขียนinterfacesทั้งสองวิธีFooและBarครอบคลุมวิธีการสาธารณะทั้งหมด เช่น
public interface FooInterface {
public void methodA();
public int methodB();
//...
}
public interface BarInterface {
public int methodC(int i);
//...
}
และตอนนี้ทำFooและBarใช้อินเทอร์เฟซแบบสัมพันธ์:
public class Foo implements FooInterface { /*...*/ }
public class Bar implements BarInterface { /*...*/ }
ขณะนี้class FooBarคุณสามารถใช้ทั้งสองFooInterfaceและBarInterfaceในขณะที่รักษาFooและBarวัตถุและเพียงผ่านวิธีการผ่าน:
public class FooBar implements FooInterface, BarInterface {
Foo myFoo;
Bar myBar;
// You can have the FooBar constructor require the arguments for both
// the Foo and the Bar constructors
public FooBar(int x, int y, int z){
myFoo = new Foo(x);
myBar = new Bar(y, z);
}
// Or have the Foo and Bar objects passed right in
public FooBar(Foo newFoo, Bar newBar){
myFoo = newFoo;
myBar = newBar;
}
public void methodA(){
myFoo.methodA();
}
public int methodB(){
return myFoo.methodB();
}
public int methodC(int i){
return myBar.methodC(i);
}
//...
}
โบนัสสำหรับวิธีนี้คือว่าFooBarวัตถุที่เหมาะกับแม่พิมพ์ของทั้งสองและFooInterface BarInterfaceนั่นหมายความว่านี่เป็นเรื่องปกติอย่างสมบูรณ์แบบ:
FooInterface testFoo;
testFoo = new FooBar(a, b, c);
testFoo = new Foo(a);
BarInterface testBar;
testBar = new FooBar(a, b, c);
testBar = new Bar(b, c);
หวังว่านี่จะอธิบายวิธีใช้อินเทอร์เฟซแทนส่วนขยายหลายรายการ แม้ว่าฉันจะไม่กี่ปีที่ผ่านมา
คุณจะต้องการใช้อินเทอร์เฟซ โดยทั่วไปแล้วการรับมรดกหลายครั้งไม่ดีเนื่องจากปัญหาเพชร:
abstract class A {
abstract string foo();
}
class B extends A {
string foo () { return "bar"; }
}
class C extends A {
string foo() {return "baz"; }
}
class D extends B, C {
string foo() { return super.foo(); } //What do I do? Which method should I call?
}
C ++ และอื่น ๆ มีวิธีแก้ไขสองสามวิธีเช่น
string foo() { return B::foo(); }
แต่ Java ใช้อินเตอร์เฟสเท่านั้น
Java Trails มีการแนะนำที่ยอดเยี่ยมเกี่ยวกับส่วนต่อประสาน: http://download.oracle.com/javase/tutorial/java/concepts/interface.html คุณอาจต้องการติดตามสิ่งนั้นก่อนที่จะดำดิ่งสู่ความแตกต่างใน Android API
virtual classไม่ได้กับ การทำเช่นนั้นมาพร้อมกับคำเตือนและคำเตือนมากมายทั้งสำหรับคอมไพเลอร์และนักพัฒนา
superจากวิธีการสืบทอด ดีคุณสามารถ แต่คุณต้องระบุวิธีการอินเตอร์เฟซที่จะเรียกใช้ (และมันจะต้องใช้คำหลักdefaultในการดำเนินการอินเตอร์เฟซ) ตัวอย่างคือ: MyIFace.super.foo()โดยที่ MyIFace เป็นอินเตอร์เฟส ในขณะที่คุณสามารถเห็นวิธีการอินเทอร์เฟซในการดำเนินการที่กำหนดไว้และหลีกเลี่ยงปัญหาเพชรทั้งหมด หากคุณขยายMyClass1และMyClass2ทั้งสองคลาสมี a foo()และเรียกsuper.foo()คอมไพเลอร์จะถูกโยนโดยปัญหาเพชร
"bar"หรือมีประเภทวิธีการ"baz" voidอย่างไรก็ตามคำอธิบายที่ดี xD
ใช่อย่างที่ทุกคนเขียนไว้คุณไม่สามารถทำมรดกหลายอย่างใน Java หากคุณมีสองคลาสที่คุณต้องการใช้รหัสคุณมักจะเป็นคลาสย่อย (พูดคลาสA) สำหรับการเรียนBคุณนามธรรมวิธีการที่สำคัญของมันมีอินเตอร์เฟซBInterface(ชื่อน่าเกลียด แต่คุณได้รับความคิด) Main extends A implements BInterfaceแล้วบอกว่า ภายในคุณสามารถยกตัวอย่างวัตถุของคลาสBและใช้วิธีการทั้งหมดBInterfaceโดยการเรียกฟังก์ชันที่เกี่ยวข้องของBโดยการเรียกฟังก์ชั่นที่สอดคล้องกันของ
นี้เปลี่ยน "เป็น-" ความสัมพันธ์กับ "มี-" ความสัมพันธ์เป็นของคุณMainตอนนี้แต่มีA Bขึ้นอยู่กับกรณีการใช้งานของคุณคุณอาจทำการเปลี่ยนแปลงนั้นอย่างชัดเจนโดยลบออกBInterfaceจากAคลาสของคุณและให้วิธีการเข้าถึงวัตถุ B ของคุณโดยตรง
สร้างอินเตอร์เฟส Java ไม่มีมรดกหลายอย่าง
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
Java ไม่สนับสนุนการสืบทอดหลายรายการ แต่คุณสามารถลองใช้สองอินเตอร์เฟสขึ้นไป
ใช่. slandau ถูกต้อง Java ไม่อนุญาตให้ขยายจากหลายคลาส
สิ่งที่คุณต้องการน่าจะเป็น public class Main extends ListActivity implements ControlMenuสิ่งที่คุณต้องการอาจจะเป็นฉันเดาว่าคุณกำลังพยายามทำรายการ
หวังว่าจะช่วย
เช่นเดียวกับทางเลือกอื่นบางทีคุณสามารถใช้อินเทอร์เฟซกับการใช้งานเริ่มต้นของวิธีการ ขึ้นอยู่กับว่าคุณต้องการทำอะไร
ตัวอย่างเช่นคุณสามารถสร้างคลาสนามธรรมและอินเทอร์เฟซ:
public abstract class FatherClass {
abstract void methodInherit() {
//... do something
}
}
public interface InterfaceWithDefaultsMethods {
default void anotherMethod() {
//... do something
//... maybe a method with a callable for call another function.
}
}
ดังนั้นหลังจากนั้นคุณสามารถขยายและใช้คลาสทั้งสองและใช้ทั้งสองวิธี
public class extends FatherClass implements InterfaceWithDefaultsMethods {
void methode() {
methodInherit();
anotherMethod();
}
}
หวังว่านี่จะช่วยคุณ ...
ไม่อนุญาตให้ขยายจากหลายคลาสในจาวา .. เพื่อป้องกันDiamond of Death !
มันเป็นไปได้
public class ParallaxViewController<T extends View & Parallaxor> extends ParallaxController<T> implements AbsListView.OnScrollListener {
//blah
}
ParallaxorและParallaxControllerไม่เป็นที่รู้จักดังนั้นฉันคิดว่ามันไม่ใช่ SDK- คลาส ดังนั้นนี่ใช้ไม่ได้สำหรับฉัน (และคำตอบนี้แสดงข้อผิดพลาด) ParallaxController คืออะไร นี่เป็นการพึ่งพาที่เฉพาะเจาะจงหรือไม่? โปรดอธิบายอย่างละเอียด
ผู้สร้างของจาวาตัดสินใจว่าปัญหาของการสืบทอดหลายครั้งมีมากกว่าผลประโยชน์ดังนั้นพวกเขาจึงไม่รวมการสืบทอดหลายรายการ คุณสามารถอ่านเกี่ยวกับหนึ่งในปัญหาที่ใหญ่ที่สุดของมรดกหลายรายการ (ปัญหาเพชรคู่) ที่นี่ที่นี่
แนวคิดที่คล้ายกันมากที่สุดสองประการคือการใช้อินเตอร์เฟสและรวมถึงวัตถุของคลาสอื่น ๆ ในฐานะสมาชิกของคลาสปัจจุบัน การใช้วิธีการเริ่มต้นในอินเทอร์เฟซเกือบจะเหมือนกับการสืบทอดหลาย ๆ ครั้งอย่างไรก็ตามมันถือว่าเป็นแนวปฏิบัติที่ไม่ดีในการใช้อินเทอร์เฟซที่มีวิธีการเริ่มต้นเท่านั้น
คุณไม่สามารถทำหลายมรดกใน java พิจารณาใช้อินเตอร์เฟส:
interface I1 {}
interface I2 {}
class C implements I1, I2 {}
หรือคลาสภายใน:
class Outer {
class Inner1 extends Class1 {}
class Inner2 extends Class2 {}
}