سؤال

أنا أحاول أن أشغل عقلي شيء في جاوة.عندما تمر كائن إلى فئة أخرى' طريقة يمكن أن مجرد دعوة أي الأساليب الكامنة في هذا الكائن الصف ؟

ما هو السبب رمز مثل المثال أدناه لا تجميع?

شكرا لك

class a {
  public static void myMethod(Object myObj) {
    myObj.testing();
  }
}


class b {
  public void testing() {
    System.out.println ("TESTING!!!");
  }
}


class c {  
  public static void main (String[] args) {
    b myB = new b();    
    a.myMethod(myB);  
  }
}

تحرير:السبب في أنني قد تركت المعلمة في myMethod حسب نوع الكائن ، لأنني أود أن تكون قادرة على تمرير في مجموعة متنوعة من أنواع الكائنات ، كل وجود اختبار الأسلوب ().

هل كانت مفيدة؟

المحلول

إذا كنت ترغب في تمرير في مجموعة متنوعة من الكائنات مع testing() أساليب يكون كل كائن تنفيذ Testable واجهة:

public interface Testable
{
   public void testing()
}

ثم يكون myMethod() اتخاذ Testable.

public static void myMethod(Testable testable)
{
  testable.testing();
}

تحرير:توضيح وتنفيذ واجهة يعني أن الطبقة يتم ضمان أن يكون الأسلوب ، ولكن الأسلوب تستطيع أن تفعل ما تريد.لذا يمكن أن يكون اثنين من الطبقات التي testing() أساليب تفعل أشياء مختلفة.

public class AClass implements Testable
{
   public void testing()
   {
      System.out.println("Hello world");
   }
}

public class BClass implements Testable
{
   public void testing()
   {
      System.out.println("Hello underworld");
   }
}

نصائح أخرى

المشكلة هي أن myMethod لا يمكن أن تعرف أنها b كائن حتى أنه يعمل في الواقع.هل يمكن تمرير String في كل ما يعلم.

تغييره إلى

public static void myMethod(b myObj) {
  myObj.testing();
}

وينبغي أن تعمل.


التحديث من السؤال:

تحرير:السبب في أنني قد تركت المعلمة في myMethod حسب نوع الكائن ، لأنني أود أن تكون قادرة على تمرير في مجموعة متنوعة من أنواع الكائنات ، كل وجود اختبار الأسلوب ().

كما أماندا S وعدة قال آخرون ، هذه حالة مثالية واجهة.طريقة للقيام بذلك هي إنشاء واجهة الذي يحدد testing() طريقة تغيير myMethod أن تأخذ الأشياء تنفيذ تلك الواجهة.

حل بديل (بدون واجهات) سيكون عاكس اكتشاف ما إذا كان الكائن يحتوي على testing() طريقة و لكن لا ينصح بذلك و لا حاجة مثل هذه الحالة البسيطة.

ما تتحدث عنه هو بطة الكتابة.جافا لا يجب بطة الكتابة.

لذلك تحتاج إلى تعريف واجهة كل الطبقات مع testing() طريقة التنفيذ.

هـ.g:

public interface Testable
{
   public void testing()
}

class B implements Testable 
{
  public void testing() {
    System.out.println ("TESTING!!!");
  }
}

class A {
  public static void myMethod(Testable myObj) {
    myObj.testing();
  }
}

المشكلة هو كلاسيكي حجة في صالح من واجهة.تريد أنها عامة ممكن بعد تريد كل كائن يمكنك تمرير إلى اختبار الأسلوب ().أقترح شيئا على غرار ما يلي:

public interface Testable
{
  public void testing();
}

public class A
{
  public static void myMethod(Testable myObj)
  {    
    myObj.testing();
  }
}

public class B implements Testable
{
  public void testing()
  {
    System.out.println("This is class B");
  }
}

public class C implements Testable
{
  public void testing()
  {
    System.out.println("This is class C");
  }
}

public class Test
{  
  public static void main (String[] args) 
  {
    B myB = new B();
    C myC = new C();
    A.myMethod(myB); // "This is class B"
    A.myMethod(myC); // "This is class C" 
  }
}

لأنك تمر في كائن (ب ترث من وجوه).كائن لا يكون اختبار ، ب لا.

يمكنك إما تمر في ب أو يلقي الكائن ب قبل استدعاء الأسلوب.

تحرير لتمرير في عام الفئة التي تطبق هذا الأسلوب:فأنت تريد أن تجعل واجهة لديها طريقة التوقيع تمر في واجهة نوع بدلا من الكائن.كل الأشياء التي كنت تمر في تنفيذ الواجهة.

يمكنك فقط الوصول إلى الأعضاء التي هي واضحة عن نوع من الإشارة لديك إلى الكائن.

في حالة myMethod(Object myObj) هذا يعني فقط أعضاء محددة في الكائن ، وذلك في class a أعضاء class b لن تكون مرئية.

إذا قمت بتغيير تعريف a.myMethod أن يكون public static void myMethod(b myObj) ثم يمكنك أن تكون قادرا على رؤية testing الطريقة على سبيل المثال من b بينما في myMethod.

تحديث استنادا إلى توضيح:

في هذه الحالة تحديد واجهة لكل منهم لتنفيذ المرجح ما تريد.

public interface Testable {
    public void testing();
}

public class a {
    public static void myMethod(Testable myObj) {
        myObj.testing();
    }
}

public class b implements Testable {
    public void testing () {
        System.out.println("TESTING!!!");
    }
}

لماذا لا جافا أجد الطريقة ؟

بسبب الطريقة التي كان جافا المصممة.

جافا "كتابتها بشكل ثابت" هذا يعني أن الكائنات أنواع فحص خلال تجميع.

في جافا يمكنك استدعاء الأسلوب فقط إذا كان هذا الأسلوب ينتمي إلى هذا النوع.

لأن هذا تتم عملية التحقق من خلال تجميع نوع الكائن لا يكون "اختبار()" طريقة تجميع فشل ( حتى ولو كان في وقت التشغيل الكائنات لا يكون هذا الأسلوب".هذا هو في المقام الأول من أجل السلامة.

الحل كما هو موضح من قبل الآخرين سوف تحتاج إلى إنشاء نوع جديد ، حيث يمكن أن أقول لكم مترجم

"يا الحالات من هذا النوع سوف الرد على طريقة الاختبار"

إذا كنت تريد أن تمر مجموعة متنوعة من الكائنات و تبقي عام واحد الطريقة هو وجود تلك الكائنات لتنفيذ واجهة.

public interface Testable { 
    public void testing();
}

class A implements Testable { // here this class commits to respond to "testing" message 
    public void testing() {
    }
}

class B implements Testable { // B "is" testable 
    public void testing() { 
        System.out.println("Testing from b");
    } 
}


class C implements Testable { // C is... etc. 
    public void testing() { 
        //.... 
    }
}

في وقت لاحق في مكان آخر

public void doTest( Testable object ) { 
    object.testing();
}

doTest( new A() );
doTest( new B() );
doTest( new C() );

"الآخر" طريقة للقيام بذلك في جاوة هو استدعاء أساليب عاكس, ولكن لست متأكدا إذا كان هذا هو ما تحتاج إليه ، رمز مجردة أكثر بكثير عندما كنت تفعل ذلك بهذه الطريقة لكن كيف الاختبار الآلي الأطر (و الكثير من أطر أخرى مثل السبات) لا تعمل في الواقع.

آمل أن يكون هذا يساعدك على توضيح السبب.

إذا كنت حقا تريد أن تبقي المعلمة مجردة ممكن, يجب عليك أن تنظر انعكاس API.بهذه الطريقة, يمكنك تمرير كل ما تريد و حيوي تنفيذ طريقة تريد.يمكنك أن تأخذ نظرة على بعض الأمثلة.

انها ليست الطريقة الوحيدة ، ولكن قد يكون بديل صالح اعتمادا على المشكلة.

نضع في اعتبارنا أن التفكير هو الطريقة أبطأ من استدعاء الأساليب الخاصة بك مباشرة.قد تفكر في استخدام واجهة مثل واحد على أماندا بعد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top