Java 无法从接口调用抽象类方法

Java 无法从接口调用抽象类方法,java,class,interface,abstract,Java,Class,Interface,Abstract,我很难掌握编程接口和同时使用抽象类的概念 我有一组“Retriever”类,它们从Internet检索不同类型的数据。这些检索器类检索JSON响应的字符串 public class AccountRetriever extends DataRetriever implements AccountInformation{ List<String> getAccountInformation{ .... } } public class BalanceRet

我很难掌握编程接口和同时使用抽象类的概念

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

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

public class BalanceRetriever extends DataRetriever implements BalanceInformation{
     List<String> getBalanceInformation{
      ....
   }
}
在使用接口在my main中实例化这些类之后:

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??
AccountInformation ai=新的AccountRetriever(apiRequest);

List aiList=ai.getAccountInformation() 这些方法不是visbale,因为当您构造
AccountRetriever
时,您的
ai
变量只属于
AccountInformation
类型,该接口只有
getAccountInformation()
而不是
getResponseAsString()

您需要将变量类型更改为
AccountRetriever
,它既扩展了
DataRetriever
,又实现了
AccountInformation

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

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

AccountRetrieverIS-AAccountInformation(实现接口)

AccountRetrieverIS-ADataRetriever(扩展抽象类)

因此,AccountRetriever引用可以同时使用AccountInformation和DataRetriever的方法

同样的逻辑也适用于BalanceRetrieverBalanceInformationDataRetriever的情况

// 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
//会有用的
BalancerTriever br=新的BalancerTriever(APIRESQUEST);
List brList=br.getBalanceInformation();
br.getResponseAsString();
//行不通
BalanceInformation bi=新的平衡器请求(APIRESQUEST)//向上投射
bi.getResponseAsString()//错误

您的问题本质上与一个简单得多的问题相同,我们对此有很多疑问。大概是这样的:

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()
时,它只知道
a
Animal
,因此无法确定
a
是否有
bark
方法。
a
所允许的唯一方法是为
Animal
定义的方法。不允许知道
a
Dog
——只能在运行时检查

你的问题是一样的,尽管它涉及到更多的复杂性

AccountInformation ai = new AccountRetriever(apiRequest);
ai.getResponseAsString();      <----this doesn't work. Why??

这将在运行时检查
ai
是否是扩展
DataRetriever
的某个类的成员,如果不是,则抛出异常。

并非所有
AccountInformation
实例都是
DataRetriever
的实例。但这不否定“编程到接口”的整个推理吗?一点也不否定。我想你的遗产又回来了。编辑后的答案将举例说明如何调整它。出于不同的原因,您可以以各种不同的方式实现。我想你只是想要一个简单的自下而上的接口方法,根本不需要抽象类。没问题。界面很酷。我发现抽象类没有那么有用。尽量不要过度使用,我很感激你的反馈。也许我只是想过度幻想。。。我现在正在编辑我的代码
public interface Information {
    public String getResponseAsString();
}

public interface AccountInformation extends Information {
    public List<String> getAccountInformation();
}

public interface BalanceInformation extends Information {
    public List<String> getBalanceInformation();
}
// Will work
AccountRetriever ar = new AccountRetriever(apiRequest);
List<String> arList = ar.getAccountInformation();
ar.getResponseAsString();
// Won't Work
AccountInformation ai = new AccountRetriever(apiRequest); //upcasting
ai.getResponseAsString(); //error
// 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
class Animal { ... }
class Dog extends Animal {
    public void bark() { ... }  // new method not inherited from Animal
}

Animal a = new Dog();
a.bark(); // ILLEGAL
AccountInformation ai = new AccountRetriever(apiRequest);
ai.getResponseAsString();      <----this doesn't work. Why??
public void someMethod(ai: AccountInformation) {
    ((DataRetriever)ai).getResponseAsString();  // LEGAL