无法从接口

时间:2017-11-24 03:46:40

标签: java class interface abstract

我有点难以把编程的概念理解为接口并同时使用抽象类。

我有一组“Retriever”类,可以从Internet检索不同类型的数据。这些检索器类检索JSON响应的字符串

public class AccountRetriever extends DataRetriever implements AccountInformation{
     List<String> getAccountInformation{
      ....
   }
}

public class BalanceRetriever extends DataRetriever implements BalanceInformation{
     List<String> getBalanceInformation{
      ....
   }
}

AccountInformation和BalanceInformation都是与其中显示的方法的接口。我也从一个抽象类“DataRetriever”扩展而来,它有一个名为

的方法
public String getResponseAsString();

在我的主要使用接口实例化这些类之后:

AccountInformation ai = new AccountRetriever(apiRequest);
List<String> aiList = ai.getAccountInformation();   <----this works
ai.getResponseAsString();      <----this doesn't work. Why??

BalanceInformation bi = new BalanceRetriever(apiRequest);
List<String> biList = bi.getBalanceInformation();   <----this works
bi.getResponseAsString();      <----this doesn't work. Why??

getResponseAsString()方法存在于每个这些检索器扩展的抽象类中,为什么我无法访问该方法?我可以访问的唯一方法是界面中的方法。我在这里做错了什么?

3 个答案:

答案 0 :(得分:1)

这些方法并不可见,因为在构建AccountRetriever时,您的ai变量只有AccountInformation类型,只有getAccountInformation()的接口没有getResponseAsString()

AccountInformation ai = new AccountRetriever(apiRequest);
List<String> aiList = ai.getAccountInformation();   <----this works
ai.getResponseAsString();      <----this doesn't work. Why??

但是,如果您将变量类型更改为DataRetriever,那么getAccountInformation()将会显示,但getAccountInformation()则不会。

DataRetriever ai = new AccountRetriever(apiRequest);
List<String> aiList = ai.getAccountInformation();   <----this wont work
ai.getResponseAsString();      <---- this will work

您需要将变量类型更改为AccountRetriever,其中DataRetriever扩展AccountInformation并实现AccountRetriever ai = new AccountRetriever(apiRequest); List<String> aiList = ai.getAccountInformation(); <----this will work ai.getResponseAsString(); <---- this will work

AccountInformation

或者,更改您的设计,以便BalanceInformationgetResponseAsString()都扩展了定义public interface Information { public String getResponseAsString(); } public interface AccountInformation extends Information { public List<String> getAccountInformation(); } public interface BalanceInformation extends Information { public List<String> getBalanceInformation(); } 的公共接口。并一起删除抽象类。

position:absolute

答案 1 :(得分:0)

你的是多重继承的一个例子。

AccountRetriever IS-A 帐户信息 (实现界面)

AccountRetriever IS-A DataRetriever (扩展抽象类)

因此 AccountRetriever参考 可以使用 AccountInformation DataRetriever 的方法。

// Will work
AccountRetriever ar = new AccountRetriever(apiRequest);
List<String> arList = ar.getAccountInformation();
ar.getResponseAsString();

帐户信息 DataRetriever <之间存在 没有IS-A 关系/ EM>

所以 帐户信息参考 无法使用 DataRetriever 的方法,即使它可能包含 AccountRetriever 实例(通过上传)

// Won't Work
AccountInformation ai = new AccountRetriever(apiRequest); //upcasting
ai.getResponseAsString(); //error

同样的逻辑适用于 BalanceRetriever BalanceInformation DataRetriever的情况

// Will work
BalanceRetriever br = new BalanceRetriever(apiRequest);
List<String> brList = br.getBalanceInformation();   
br.getResponseAsString(); 

// Won't work
BalanceInformation bi = new BalanceRetriever(apiRequest); //upcasting
bi.getResponseAsString(); //error

答案 2 :(得分:0)

您的问题基本上与一个更简单的问题相同,我们会遇到很多问题。像这样:

class Animal { ... }
class Dog extends Animal {
    public void bark() { ... }  // new method not inherited from Animal
}

Animal a = new Dog();
a.bark(); // ILLEGAL

较新的程序员无法弄清楚为什么a.bark()不合法。答案当然是,当编译器看到a.bark()时,它只知道aAnimal,因此无法确定a是否有bark a方法。 Animal允许的唯一方法是为a定义的方法。我们不允许知道DogAccountInformation ai = new AccountRetriever(apiRequest); ai.getResponseAsString(); <----this doesn't work. Why?? - 只能在运行时检查。

你的问题是一样的,虽然它涉及更多的复杂性。

ai

AccountInformation被声明为AccountInformation;因此,可以在其上使用的唯一方法是为AccountInformation接口声明的方法。毕竟,你可以声明另一个实现DataRetriever但不扩展ai的类,而getResponseString可以是该类的对象,在这种情况下没有AccountInformation方法。

请注意,如果您有DataRetriever个对象,并且您确定它也是public void someMethod(ai: AccountInformation) { ((DataRetriever)ai).getResponseAsString(); // LEGAL ,则可以转换为该对象。

ai

这将在运行时检查DataRetriever是否是某个扩展function ajaxFunction(str,id) { jQuery.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'post', data: { 'action' : 'my_action', 'payment_selected': payment_selected, 'id' : id }, success: function (response) { if(response=='success'){ jQuery("#status").html(response); } } }); } 的类的成员,如果不是则抛出异常。