Java 接口、抽象类和抽象类的方法
我正在学习如何使用工厂模式在Java中创建对象。我想创建管理汽车的类。汽车可以是小的也可以是大的。我创建了一个接口,该接口定义了要由实现类实现的方法。抽象类实现了小型车和大型车共享的接口的一些常用方法。具体的SmallCar和LargeCar类实现了抽象类的其余方法 汽车界面Java 接口、抽象类和抽象类的方法,java,oop,interface,abstract-class,late-binding,Java,Oop,Interface,Abstract Class,Late Binding,我正在学习如何使用工厂模式在Java中创建对象。我想创建管理汽车的类。汽车可以是小的也可以是大的。我创建了一个接口,该接口定义了要由实现类实现的方法。抽象类实现了小型车和大型车共享的接口的一些常用方法。具体的SmallCar和LargeCar类实现了抽象类的其余方法 汽车界面 public interface Car { String getRegistrationNumber(); void drive(); } public abstract class AbstractCar imp
public interface Car {
String getRegistrationNumber();
void drive();
}
public abstract class AbstractCar implements Car {
private final RegistrationNumber regNumber;
private boolean tankFull = true;
public AbstractCar(RegistrationNumber regNumber) {
this.regNumber = regNumber;
}
@Override
public final String getregistrationNumber() {
return regNumber.toString();
}
/**This method is not defined in the implemented Car interface. I added it to
*the abstract class because I want subclasses of these abstract class
*to have this method*/
public boolean isTankFull() {
return tankFull;
}
}
抽象CAR类实现CAR接口
public interface Car {
String getRegistrationNumber();
void drive();
}
public abstract class AbstractCar implements Car {
private final RegistrationNumber regNumber;
private boolean tankFull = true;
public AbstractCar(RegistrationNumber regNumber) {
this.regNumber = regNumber;
}
@Override
public final String getregistrationNumber() {
return regNumber.toString();
}
/**This method is not defined in the implemented Car interface. I added it to
*the abstract class because I want subclasses of these abstract class
*to have this method*/
public boolean isTankFull() {
return tankFull;
}
}
小型车扩展了抽象类
public final class SmallCar extends AbstractCar {
public SmallCar(RegistrationNumber regNum) {
super(regNum);
}
@Override
public void drive() {
//implemented here
}
}
工厂级:
此类负责创建特定类型汽车的实例。
public final class CarFactory {
public static Car createCar(String carType, RegistrationNumber regNum) {
Car car = null;
if (carType.equals("Small") {
car = new SmallCar(regNum);
}
return car;
}
主要方法
RegistrationNumber regNum = new RegistrationNumber('a', 1234);
Car c = CarFactory.createCar("Small", regNum);
c.getRegistrationNumber(); //this works
c.isTankFull(); //this instance of Car cannot access the isTankFull method defined on the abstract class. The method is not defined on the Car interface though. I do not understand why.
挑战在于Car实例可以访问Car接口上定义的所有其他方法,但不能访问抽象类上定义但接口上未定义的
isTankFull()
方法。我希望我的解释足够清楚 无法看到方法的原因是,您的c
对象被声明为Car
接口。当然,当它来自工厂方法时,它是一个SmallCar
,但是您的变量只有接口。您可以将声明更改为AbstractCar c=CarFactory.createCar(“SmallCar”,regnum)代码>
另一种方法是在使用接口时将c
对象强制转换为AbstractCar
,在尝试访问接口上不存在的方法时,您需要小心,因为您的工厂总是可能返回实现Car
的对象,但不是AbstractCar
if (c instanceof AbstractCar) {
((AbstarctCar)c).isTankFull();
}
当然,另一个简单的解决方案是将该方法添加到接口中,尽管这会消除该问题的教学机会。之所以看不到该方法,是因为您的c
对象被声明为Car
接口。当然,当它来自工厂方法时,它是一个SmallCar
,但是您的变量只有接口。您可以将声明更改为AbstractCar c=CarFactory.createCar(“SmallCar”,regnum)代码>
另一种方法是在使用接口时将c
对象强制转换为AbstractCar
,在尝试访问接口上不存在的方法时,您需要小心,因为您的工厂总是可能返回实现Car
的对象,但不是AbstractCar
if (c instanceof AbstractCar) {
((AbstarctCar)c).isTankFull();
}
当然,另一个简单的解决方案是将该方法添加到接口中,尽管这会消除该问题的教学机会。好的解决方案是将您的isTankFull()
放在接口上。这是有意义的,因为任何实现car
的汽车都需要访问isTankFull()
问题是:您是否正在创建任何无法回答问题的isTankFull
汽车?如果是这样,那么将isTankFull
移动到接口将没有意义
另一种解决方案(如果您不希望isTankFull()
出现在界面上),是将汽车转换为适当的类型:
if (c instanceof AbstractCar) {
((AbstractCar)c).isTankFull();
}
好的解决方案是将isTankFull()
放在界面上。这是有意义的,因为任何实现car
的汽车都需要访问isTankFull()
问题是:您是否正在创建任何无法回答问题的isTankFull
汽车?如果是这样,那么将isTankFull
移动到接口将没有意义
另一种解决方案(如果您不希望isTankFull()
出现在界面上),是将汽车转换为适当的类型:
if (c instanceof AbstractCar) {
((AbstractCar)c).isTankFull();
}
接口是您与实现它的类的用户签订的契约(或协议)。因此,您必须扪心自问,是否有任何汽车应该公开信息isTankFull
(即应该响应消息isTankFull
)。如果回答为“是”,则必须将方法isTankFull
添加到接口中
看看您的代码,类AbstractCar
似乎只是一个实用类。然后,应该将方法isTankFull
提升到接口,或者至少使其受到保护
另一方面,您必须问问自己,您的客户机代码(即main方法)是否真的需要一辆通用的汽车
,或者它是否需要一种特定类型的汽车,例如小型汽车
最后,请记住,使用接口可以最大限度地减少组件之间的依赖关系。接口是您与实现它的类的用户签订的合同(或协议)。因此,您必须扪心自问,是否有任何汽车应该公开信息isTankFull
(即应该响应消息isTankFull
)。如果回答为“是”,则必须将方法isTankFull
添加到接口中
看看您的代码,类AbstractCar
似乎只是一个实用类。然后,应该将方法isTankFull
提升到接口,或者至少使其受到保护
另一方面,您必须问问自己,您的客户机代码(即main方法)是否真的需要一辆通用的汽车
,或者它是否需要一种特定类型的汽车,例如小型汽车
最后,请记住,使用接口可以最大限度地减少组件之间的依赖性。没什么奇怪的