我正在尝试使用我在数组列表中的类中的方法。
ArrayList是ArrayList,而Appliance是超类。
ArrayList包含扩展设备的对象,如时钟和灯。
当我使用
时arrayList.get(x)在那一点抓住对象我看不到对象有的方法,我只能看到superClass对象。
请有人帮助我。
感谢您阅读
代码(其中一些)
public abstract class Appliance implements Serializable {
protected boolean power;
protected ImageIcon picture;
public Appliance() {
}
public void setPower(boolean power) {
this.power = power;
}
public boolean getPower() {
return power;
}
abstract ImageIcon getPicture();
@Override
public String toString() {
String powerVal;
if (this.power == true) {
powerVal = "ON";
} else {
powerVal = "OFF";
}
return "Power: " + powerVal;
}
}
public class Clock extends Appliance {
private int hours;
private int minutes;
private int seconds;
public Clock() {
super();
this.power = false;
this.picture = new ImageIcon("src/res/clock.jpg");
this.hours = 23;
this.minutes = 59;
this.seconds = 59;
}
public Clock(boolean pow, int hours, int minutes, int seconds) {
super();
this.power = pow;
this.picture = new ImageIcon("src/res/clock.jpg");
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
}
public int getHour() {
return this.hours;
}
public void setHours(int hours) {
this.hours = hours;
}
public int getMinutes() {
return this.minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
public int getSeconds() {
return this.seconds;
}
public void setSeconds(int seconds) {
this.seconds = seconds;
}
@Override
public ImageIcon getPicture() {
return this.picture;
}
@Override
public String toString(){
return super.toString() + String.format(" and the time is %d:%d:%d",this.hours, this.minutes, this.seconds);
}
}
public class Lamp extends Appliance{
//Default constructor or Empty argument constructor
public Lamp(){
super();
this.power = false;
this.picture = new ImageIcon("src/res/lamp.jpg");
}
public Lamp(boolean pow){
super();
this.power = pow;
this.picture = new ImageIcon("src/res/lamp.jpg");
}
@Override
ImageIcon getPicture() {
return picture;
}
@Override
public String toString(){
return super.toString();
}
}
public class Controller {
private ArrayList<Appliance> myAppliances = new ArrayList<>();
private JLabel[] labelArray;
...................................................
@Override
public void mouseClicked(MouseEvent me) {
String[] options = new String[]{"yes","no"};
if (me.getButton() == 1){
try{
int x = Integer.parseInt( me.getComponent().getName());
Appliance myApp = this.myAppliances.get(x);
if(myApp.getClass().equals(Clock.class)){
JOptionPane.showOptionDialog(null, "Clock Info: /nTime: " + myApp., "Clock", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,options,options[1] );
}
} catch (Exception e){
System.out.println("Null Poiter");
}
}
}
}
Its the myApp. part in the clicked method
答案 0 :(得分:2)
我认为你正在做这样的事情(抱歉,但你的问题并不清楚):
ArrayList<SuperClass> al;
...populated with instances of Appliance
al.get(1).getClock(); //Compile error.
问题是java不知道你那个位置的元素是SuperClass,Appliance还是其他从SuperClass继承的元素。您可以转换代码,使其按照您想要的方式运行:
((Appliance)al.get(1)).getClock();
您可能还想使用instanceOf
运算符来确保您拥有您期望的类的实例。
答案 1 :(得分:0)
这听起来像是在写
List<Appliance> appliances = new ArrayList<>();
appliances.add(new Lamp());
appliances.add(new Clock());
Appliance appliance = appliances.get(0);
appliance.setAlarm(TOMORROW);
我认为从这个例子中你可以看出为什么你不能访问子类方法。当你有一个设备列表时,你不知道它中的对象是时钟还是灯,所以当你拿到一个时,你就不能调用子类方法。
如果你肯定对象是一个时钟,你可以施展它:
Clock clock = (Clock) appliances.get(1);
clock.setAlarm(TOMORROW);
但这不是Java Way。通常,您只能在Appliance上使用超类方法,或者为Clocks和Lamps维护一个单独的列表。
答案 2 :(得分:0)
ArrayList<Appliance> mylist = new ArrayList();
for(Appliance app : mylist){
boolean isAclock = app instanceof Clock;
boolean isALamp = app instanceof Lame;
if(isAlamp){
Lamp l = (Lamp)app;
}else{
Clock c = (Clock)app;
}
}
让你的集会者接受appliacnces将接受它的子类bt问题是接收正确的类对象。您可以使用实例并检查对象类型,然后将对象强制转换为其原始类型 尝试使用这种方法
答案 3 :(得分:0)
这是预期的行为。它是多态的工作原理。
让我们看看使用您自己的类的示例。想象一下拿着一个包。你知道只有Appliance
个物品可以放进这个包里,所以你可以把你家里的所有电器放到这个包里 - 你的Lamp
,你的Clock
,也许你的{{1}和Toaster
以及其他一些人。
现在想象你戴上眼罩并随机拉出其中一个电器。不看它,你怎么知道它是什么设备?你不能!如果你认为你刚拔出的东西是Blender
并且你试图Toaster
你的面包,那么如果你真的拿着toast()
会怎么样?你可能会得到一个血腥的混乱。因此,您唯一知道所有Blender
个对象可以执行的事实是Appliance
或turnOn()
,因此这些是您可用的唯一方法。
在此示例中,您是编译器,包是列表。如果您告诉编译器列表只能包含turnOff()
个对象,它将不会假设列表中的对象有任何其他内容,除非您明确告诉它(例如,如果你是垂头丧气的话)通过Appliance
)之类的操作将Appliance
对象转换为Toaster
。