如何访问子 class 中的获取和设置?
How can I access gets and sets in a sub class?
在此应用程序中,我们有 Automovel class:
public class Automovel {
private String marca;
private String matricula;
private String anoConstrucao;
private Motor motor;
private int preco = 0;
}
(及其构建器、getter 和 setter)还有一个名为 Motor 的 class,它是 Automovel class.
的一个属性
电机Class:
private int potencia;
public Motor() {}
public Motor(int potencia){
this.potencia = potencia;
}
public int getPotencia() {return this.potencia;}
public void setPotencia(int potencia) {
this.potencia = potencia
}
这个 class 也有 2 个子class(MotorEletrico 和 MotorCombustao):
Motor Elétrico:
public class MotorEletrico extends Motor {
private int autonomia;
public MotorEletrico() {}
public MotorEletrico(int potencia, int autonomia) {
super(potencia);
this.autonomia = autonomia;
}
public int getAutonomia() {
return autonomia;
}
public void setAutonomia(int autonomia) {
this.autonomia = autonomia;
}
}
电机燃烧:
public class MotorCombustao extends Motor{
private int cilindrada;
private String combustivel;
public MotorCombustao(){}
public MotorCombustao(int potencia, int cilindrada, String combustivel){
super(potencia);
this.cilindrada = cilindrada;
this.combustivel = combustivel;
}
public int getCilindrada(){
return cilindrada;
}
public void setCilindrada(int cilindrada){
this.cilindrada = cilindrada;
}
public String getCombustivel(){
return combustivel;
}
public void setCombustivel(String combustivel){
this.combustivel = combustivel;
}
}
我将带有 X 引擎的汽车存储在 Automovel 对象数组中,但是当我尝试访问子class (MotorCombustao / MotorEletrico) 的 getter 和 setter 时,只有 gets 和 sets母亲 class (Motor) 出现了。我的问题是我无法访问电机 subclasses 的 getter 和 setter。
这是我尝试过的示例:
Automovel arrayteste[] = new Automovel[49];
Motor motor1 = new MotorEletrico();
motor1.setPotencia(5);
Automovel automovel1 = new Automovel("Opel", "xx-12-xx", "2000", motor1, 2000);
arrayteste[0] = automovel1;
System.out.println(arrayteste[0].getMotor().getPotencia()); //Here, I can't Do .getAutonomia
简答
你需要投
System.out.println(((MotorElettrico)(arrayteste[0].getMotor())).getAutonomia());
TL;DR
当你写
Motor motor1 = new MotorElettrico();
您正在使用 多态性。
这非常有用,例如,当您有一个 Motor
列表,其中包含不止一种电机类型并且您想要打印所有这些时 potencia
。
那你可以这样写:
List<Motor> list = Arrays.asList(new MotorElectico(), new MotorCombustao());
// ----- some set
print(list);
打印方法是这样的:
public void print(List<Motor> list){
for(Motor m : list){
System.out.println(String.format("Potencia %d", m.getPotencia()));
}
}
发生这种情况是因为 MotorElectico IS A 电机和 向上转换(转换为超类型)总是被允许的。
在你的情况下,你必须做 向下转换:你告诉编译器 arraytest[0].getMotor()
包含一个 Motor
但是这个 Motor
实际上是一个 MotorElectrico
:你要求编译器信任你。如果在编译时 arraytest[0].getMotor()
不应该是 MotorElectrico
你会得到 ClassCastException
.
你需要将父class的引用转换为相应的子class 如果你想访问一个不是从父[=34继承的方法=] 例如getAutonomia()
方法不是从 Motor
继承的,因此,您需要先将 Motor
的引用转换为 MotorEletrico
,然后才能访问 getAutonomia()
。下面给出一些更有用的代码:
public class Main {
public static void main(String[] args) {
Automovel arrayteste[] = new Automovel[2];
Motor motor;
motor = new MotorEletrico(5, 10);
arrayteste[0] = new Automovel("Opel", "xx-12-xx", "2000", motor, 2000);
motor = new MotorCombustao(7, 4, "xx-yy-zz");
arrayteste[1] = new Automovel("Opel", "xx-08-xx", "1995", motor, 1995);
for (Automovel automovel : arrayteste) {
motor = automovel.getMotor();
if (motor instanceof MotorEletrico) {
System.out.println(((MotorEletrico) motor).getAutonomia());
}
if (automovel.getMotor() instanceof MotorCombustao) {
System.out.println(((MotorCombustao) motor).getCilindrada());
System.out.println(((MotorCombustao) motor).getCombustivel());
}
}
}
}
输出:
10
4
xx-yy-zz
[更新:以下更新基于您的评论]
另一种迭代arrayteste
的方法如下:
for (int i = 0; i < arrayteste.length; i++) {
if (arrayteste[i] != null) {
motor = arrayteste[i].getMotor();
if (motor instanceof MotorEletrico) {
System.out.println(((MotorEletrico) motor).getAutonomia());
}
if (arrayteste[i].getMotor() instanceof MotorCombustao) {
System.out.println(((MotorCombustao) motor).getCilindrada());
System.out.println(((MotorCombustao) motor).getCombustivel());
}
}
}
我假设您熟悉 Liskov substitution principle。
如果你不知道电机的类型,你可以写一个语句来询问 Automovel 数组 arraytest[i]
的每个实例是什么 class 。
例如:
List<Automovel> arrayteste = new ArrayList<>();
Motor motor1 = new MotorEletrico();
motor1.setPotencia(5);
Automovel automovel1 = new Automovel("Opel", "xx-12-xx", "2000", motor1, 2000);
arrayteste.add(automovel1);
Motor motor = new Motor();
String motorClass;
String[] motorTypes = {"MotorEletrico", "MotorCombustao"};
Set<String> motorClasses = new HashSet<>(Arrays.asList(motorTypes));
for (int i = 0; i < arrayteste.size(); i++)
{
motorClass = arrayteste.get(i).getMotor().getClass().getName();
if (motorClasses.contains(motorClass))
{
if (motorClass.equals("MotorEletrico"))
{
motor = (MotorEletrico)(arrayteste.get(i).getMotor());
}
else if (motorClass.equals("MotorCombustao"))
{
motor = (MotorCombustao)(arrayteste.get(i).getMotor());
}
System.out.println("Automovel #" + i + " : " + motor.getPotencia());
}
else
{
System.out.println("Não sei que classe de motor é esse . . .");
}
}
}
但更仔细地探索 class 设计可能会更好。
可能尝试使用接口。
在此应用程序中,我们有 Automovel class:
public class Automovel {
private String marca;
private String matricula;
private String anoConstrucao;
private Motor motor;
private int preco = 0;
}
(及其构建器、getter 和 setter)还有一个名为 Motor 的 class,它是 Automovel class.
的一个属性电机Class:
private int potencia;
public Motor() {}
public Motor(int potencia){
this.potencia = potencia;
}
public int getPotencia() {return this.potencia;}
public void setPotencia(int potencia) {
this.potencia = potencia
}
这个 class 也有 2 个子class(MotorEletrico 和 MotorCombustao):
Motor Elétrico:
public class MotorEletrico extends Motor {
private int autonomia;
public MotorEletrico() {}
public MotorEletrico(int potencia, int autonomia) {
super(potencia);
this.autonomia = autonomia;
}
public int getAutonomia() {
return autonomia;
}
public void setAutonomia(int autonomia) {
this.autonomia = autonomia;
}
}
电机燃烧:
public class MotorCombustao extends Motor{
private int cilindrada;
private String combustivel;
public MotorCombustao(){}
public MotorCombustao(int potencia, int cilindrada, String combustivel){
super(potencia);
this.cilindrada = cilindrada;
this.combustivel = combustivel;
}
public int getCilindrada(){
return cilindrada;
}
public void setCilindrada(int cilindrada){
this.cilindrada = cilindrada;
}
public String getCombustivel(){
return combustivel;
}
public void setCombustivel(String combustivel){
this.combustivel = combustivel;
}
}
我将带有 X 引擎的汽车存储在 Automovel 对象数组中,但是当我尝试访问子class (MotorCombustao / MotorEletrico) 的 getter 和 setter 时,只有 gets 和 sets母亲 class (Motor) 出现了。我的问题是我无法访问电机 subclasses 的 getter 和 setter。 这是我尝试过的示例:
Automovel arrayteste[] = new Automovel[49];
Motor motor1 = new MotorEletrico();
motor1.setPotencia(5);
Automovel automovel1 = new Automovel("Opel", "xx-12-xx", "2000", motor1, 2000);
arrayteste[0] = automovel1;
System.out.println(arrayteste[0].getMotor().getPotencia()); //Here, I can't Do .getAutonomia
简答
你需要投
System.out.println(((MotorElettrico)(arrayteste[0].getMotor())).getAutonomia());
TL;DR
当你写
Motor motor1 = new MotorElettrico();
您正在使用 多态性。
这非常有用,例如,当您有一个 Motor
列表,其中包含不止一种电机类型并且您想要打印所有这些时 potencia
。
那你可以这样写:
List<Motor> list = Arrays.asList(new MotorElectico(), new MotorCombustao());
// ----- some set
print(list);
打印方法是这样的:
public void print(List<Motor> list){
for(Motor m : list){
System.out.println(String.format("Potencia %d", m.getPotencia()));
}
}
发生这种情况是因为 MotorElectico IS A 电机和 向上转换(转换为超类型)总是被允许的。
在你的情况下,你必须做 向下转换:你告诉编译器 arraytest[0].getMotor()
包含一个 Motor
但是这个 Motor
实际上是一个 MotorElectrico
:你要求编译器信任你。如果在编译时 arraytest[0].getMotor()
不应该是 MotorElectrico
你会得到 ClassCastException
.
你需要将父class的引用转换为相应的子class 如果你想访问一个不是从父[=34继承的方法=] 例如getAutonomia()
方法不是从 Motor
继承的,因此,您需要先将 Motor
的引用转换为 MotorEletrico
,然后才能访问 getAutonomia()
。下面给出一些更有用的代码:
public class Main {
public static void main(String[] args) {
Automovel arrayteste[] = new Automovel[2];
Motor motor;
motor = new MotorEletrico(5, 10);
arrayteste[0] = new Automovel("Opel", "xx-12-xx", "2000", motor, 2000);
motor = new MotorCombustao(7, 4, "xx-yy-zz");
arrayteste[1] = new Automovel("Opel", "xx-08-xx", "1995", motor, 1995);
for (Automovel automovel : arrayteste) {
motor = automovel.getMotor();
if (motor instanceof MotorEletrico) {
System.out.println(((MotorEletrico) motor).getAutonomia());
}
if (automovel.getMotor() instanceof MotorCombustao) {
System.out.println(((MotorCombustao) motor).getCilindrada());
System.out.println(((MotorCombustao) motor).getCombustivel());
}
}
}
}
输出:
10
4
xx-yy-zz
[更新:以下更新基于您的评论]
另一种迭代arrayteste
的方法如下:
for (int i = 0; i < arrayteste.length; i++) {
if (arrayteste[i] != null) {
motor = arrayteste[i].getMotor();
if (motor instanceof MotorEletrico) {
System.out.println(((MotorEletrico) motor).getAutonomia());
}
if (arrayteste[i].getMotor() instanceof MotorCombustao) {
System.out.println(((MotorCombustao) motor).getCilindrada());
System.out.println(((MotorCombustao) motor).getCombustivel());
}
}
}
我假设您熟悉 Liskov substitution principle。
如果你不知道电机的类型,你可以写一个语句来询问 Automovel 数组 arraytest[i]
的每个实例是什么 class 。
例如:
List<Automovel> arrayteste = new ArrayList<>();
Motor motor1 = new MotorEletrico();
motor1.setPotencia(5);
Automovel automovel1 = new Automovel("Opel", "xx-12-xx", "2000", motor1, 2000);
arrayteste.add(automovel1);
Motor motor = new Motor();
String motorClass;
String[] motorTypes = {"MotorEletrico", "MotorCombustao"};
Set<String> motorClasses = new HashSet<>(Arrays.asList(motorTypes));
for (int i = 0; i < arrayteste.size(); i++)
{
motorClass = arrayteste.get(i).getMotor().getClass().getName();
if (motorClasses.contains(motorClass))
{
if (motorClass.equals("MotorEletrico"))
{
motor = (MotorEletrico)(arrayteste.get(i).getMotor());
}
else if (motorClass.equals("MotorCombustao"))
{
motor = (MotorCombustao)(arrayteste.get(i).getMotor());
}
System.out.println("Automovel #" + i + " : " + motor.getPotencia());
}
else
{
System.out.println("Não sei que classe de motor é esse . . .");
}
}
}
但更仔细地探索 class 设计可能会更好。 可能尝试使用接口。