Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 接口、抽象类和抽象类的方法_Java_Oop_Interface_Abstract Class_Late Binding - Fatal编程技术网

Java 接口、抽象类和抽象类的方法

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

我正在学习如何使用工厂模式在Java中创建对象。我想创建管理汽车的类。汽车可以是小的也可以是大的。我创建了一个接口,该接口定义了要由实现类实现的方法。抽象类实现了小型车和大型车共享的接口的一些常用方法。具体的SmallCar和LargeCar类实现了抽象类的其余方法

汽车界面

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方法)是否真的需要一辆通用的
汽车
,或者它是否需要一种特定类型的汽车,例如
小型汽车

最后,请记住,使用接口可以最大限度地减少组件之间的依赖性。

没什么奇怪的