java 遵循Decorator模式时出现ClassCastException

tquggr8v  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(148)

我正在学习在Java中结合使用装饰器模式和模板方法。我有一个编译错误

Exception in thread "main" java.lang.ClassCastException: class Room cannot be cast to class Flat (Room and Flat are in unnamed module of loader 'app')
    at Main.main(Main.java:11)

但我不知道为什么会这样,也不知道如何纠正。简单地说,我的程序必须计算公寓的面积加上房间的面积,客户可以将公寓添加到他们的购物篮中。所以我也创建了一个抽象类Premise for Flats and Rooms。

public abstract class Premise {
    protected double dwellingArea;
    protected double totalArea;
    public String getInfo(){ return "Rooms: "; }
    public abstract double getDwellingArea();
    public abstract double getTotalArea();
}

我也有一个抽象类Decorator。

public abstract class Decorator extends Premise {
    public abstract String getInfo();
    Decorator(double totalArea){
        this.totalArea=totalArea;
    }
}

之后,我创建了类Flat,它扩展了类Premise。

public class Flat extends Premise{
    private int floor;
    private double price;
    private String description;
    public int getFloor() {
        return floor;
    }
    public void setFloor(int floor) {
        this.floor = floor;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Flat(int floor, double price, String description) {
        super();
        this.floor = floor;
        this.price = price;
        this.description=description;
    }
    @Override
    public double getDwellingArea() {
        return dwellingArea;
    }
    @Override
    public double getTotalArea() {
        return totalArea;
    }
}

教室延伸装饰。

public class Room extends Decorator{
    boolean isService;
    Premise apartment;

    @Override
    public String getInfo() {
        if(isService) {
            return apartment.getInfo()+" "+"service room ";
        }
        else {
            return apartment.getInfo()+" "+"dwelling room ";
        }
    }

    @Override
    public double getDwellingArea() {
        return apartment.dwellingArea+this.dwellingArea;
    }

    @Override
    public double getTotalArea() {
        return apartment.totalArea+this.totalArea;
    }

    Room(double totalArea, boolean isService, Premise apartment) {
        super(totalArea);
        this.isService=isService;
        if(isService=true) {
            dwellingArea=0;
        }
        else {
            dwellingArea=totalArea;
        }
        this.apartment=apartment;
    }
}

另外,我有一个抽象类User,用于客户和房地产经纪人。

public abstract class User {
    protected String name;
    protected String phone;
    protected String email;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public User(String name, String phone, String email) {
        this.name = name;
        this.phone = phone;
        this.email = email;
    }
    public abstract void showList();
}

在Customer类中有一个所选单位的数组列表。

import java.util.ArrayList;
public class Customer extends User{
    private ArrayList<Flat> flats;
    public Customer(String name, String phone, String email) {
        super(name, phone, email);
        flats=new ArrayList<Flat>();
    }
    @Override
    public void showList() {
        System.out.println("Customer "+name+" selected "+flats.size()+" apartments:");
        for(Flat flat:flats) {
            System.out.println(flat.getDescription());
        }
        
    }
    public void addFlat(Flat flat) {
        flats.add(flat);
    }
}

在Main类中,我试图创建公寓及其房间和客户,然后将公寓添加到客户列表中,但它给了我上面提到的错误。

public class Main {

    public static void main(String[] args) {
        Premise flat1 = new Flat(5,25000,"A flat in a big city");
        flat1 = new Room(15, true, (Flat)flat1);
        Flat flat2 = new Flat(10,45000,"A flat in a large city"); 
        Customer client1 = new Customer("Jane Peterson","0950297789","jane@gmail.com"); 
        client1.addFlat((Flat)flat1); 
        client1.addFlat(flat2); 
    }

}

如果你告诉我为什么会这样,以及如何解决这个问题,我将非常感激。

x8diyxa7

x8diyxa71#

一个Room是一个Decorator是一个Premise。但它不是一个Flat。(您在第8行中创建的Room有一个Flat作为它的Premise apartment成员,但这并不使它成为一个Flat!)
至于修复这个问题...你必须找到一种方法将getDescription()方法移动到Premise类。这样,你的Customer可以有一个List<Premise>而不是一个ArrayList<Flat>。将addFlat(Flat flat)方法替换为addPremise(Premise premise),并在调用main()中的新方法时删除对Flat的转换。
顺便说一句:为什么你认为装饰者模式是一个很好的建模方法?一个房间装饰另一个房屋意味着什么?一个房间(如果单独租用)不就是另一个房屋吗?

相关问题