2
\$\begingroup\$

I am new to programming and I have tried to recreate below lines into OOP's code. Please review and provide comments.

House has Rooms.Rooms are drawing room, bed room, bathroom etc.Each room has walls, ceiling,floor. Each room have different objects in it like drawing room has sofa, table , TV etc. , bedroom has TV etc.

//House class
import java.util.List;

public class House{

    private List<Room> rooms;

    public House(List<Room> rooms){
        this.rooms = rooms;
    }

    public void getHouseDetails(){
        System.out.println("The House has "+this.rooms.size()+" room");
        System.out.println("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
        for(Room room:rooms){
            room.getRoomDetails();
            System.out.println("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
        }

    }
}

//Room class
import java.util.List;

public class Room{

    private List<Wall> walls;
    private Ceiling ceiling;
    private Floor floor;

    public Room(List<Wall> walls,Ceiling ceiling,Floor floor){
        this.walls = walls;
        this.ceiling = ceiling;
        this.floor = floor;
    }

    public List<Wall> getWalls(){
        return this.walls;
    }

    public Ceiling getCeiling(){
        return this.ceiling;
    }

    public Floor getFloor(){
        return this.floor;
    }

    public void getRoomDetails(){
    }

}

//Wall class
public class Wall{

    private String type;
    private String color;

    public Wall(String type, String color){
        this.type = type;
        this.color = color;
    }

    public void getWallDetails(){
        System.out.println("Wall is made up of "+this.type+" and is of "+this.color+" color");
    }


}

//Ceiling class
public class Ceiling{

    private String make;
    private String color;

    public Ceiling(String make,String color){
        this.make = make;
        this.color = color;
    }

    public void getCeilingDetails(){
        System.out.println("Ceiling is made up of "+this.make+" and is of "+this.color+" color");
    }

}

//Floor class
public class Floor{

    private String make;

    public Floor(String make){
        this.make = make;
    }

    public void getFloorDetails(){
        System.out.println("Floor is made up of "+this.make);
    }

}

//Sofa class
public class Sofa{

    private String type;
    private int number;

    public Sofa(String type,int number){
        this.type = type;
        this.number = number;
    }

    public void getSofaDetails(){
        System.out.println("There is "+this.number+" Sofa which are "+this.type+" type");
    }

}

//Chair class
public class Chair{

    private String type;
    private int number;

    public Chair(String type,int number){
        this.type = type;
        this.number = number;
    }

    public void getChairDetails(){
        System.out.println("There is "+this.number+" chair which are "+this.type+" type");
    }

}

//TV class
public class TV{

    private String type;
    private String make;
    private int number;

    public TV(String type,String make,int number){
        this.type = type;
        this.make = make;
        this.number = number;
    }

    public void getTVDetails(){
        System.out.println("There is "+this.number+" TV which is "+this.type+" type ,manufactured by "+this.make);
    }
}

//Table class
public class Table{

    private String type;
    private int number;

    public Table(String type,int number){
        this.type = type;
        this.number = number;
    }

    public void getTableDetails(){
        System.out.println("There is "+this.number+" Table which is of "+this.type);
    }
}

//Drawing Room class 
import java.util.List;

public class DrawingRoom extends Room{

    private Sofa sofa;
    private Chair chair;
    private TV tv;
    private Table table;

    public DrawingRoom(List<Wall> walls,Ceiling ceiling,Floor floor,Sofa sofa,Chair chair,TV tv,Table table){
        super(walls,ceiling,floor);
        this.sofa = sofa;
        this.chair = chair;
        this.tv = tv;
        this.table = table;
    }

    @Override
    public void getRoomDetails(){
        System.out.println(this.getClass().getSimpleName());
        getWalls().get(getWalls().size()-1).getWallDetails();
        getCeiling().getCeilingDetails();
        getFloor().getFloorDetails();
        this.sofa.getSofaDetails();
        this.chair.getChairDetails();
        this.tv.getTVDetails();
        this.table.getTableDetails();
    }

}

//Bed Room class
import java.util.List;

public class BedRoom extends Room{

    private TV tv;

    public BedRoom(List<Wall> walls,Ceiling ceiling,Floor floor,TV tv){
        super(walls,ceiling,floor);
        this.tv = tv;
    }

    @Override
    public void getRoomDetails(){
        System.out.println(this.getClass().getSimpleName());
        getWalls().get(getWalls().size()-1).getWallDetails();
        getCeiling().getCeilingDetails();
        getFloor().getFloorDetails();
        this.tv.getTVDetails();
    }

}

//Bath Room class
import java.util.List;

public class BathRoom extends Room{

    private TV tv;

    public BathRoom(List<Wall> walls,Ceiling ceiling,Floor floor){
        super(walls,ceiling,floor);
    }

    @Override
    public void getRoomDetails(){
        System.out.println(this.getClass().getSimpleName());
        getWalls().get(getWalls().size()-1).getWallDetails();
        getCeiling().getCeilingDetails();
        getFloor().getFloorDetails();
    }

}

//Main class
import java.util.List;
import java.util.ArrayList;

public class HouseTest{

    public static void main(String [] args){

        List<Wall> wall = new ArrayList<Wall>();
        List<Room> room = new ArrayList<Room>();        

        wall.add(new Wall("Cement","Yellow"));

        room.add(new DrawingRoom(wall,new Ceiling("Cement","Purple"),new Floor("Marble"),new Sofa("Leather",4),new Chair("Wooden",2),new TV("LED Plasma","Samsung",1),new Table("Glass",1)));

        room.add(new BedRoom(wall,new Ceiling("Cement","Purple"),new Floor("Marble"),new TV("LED Plasma","Samsung",1)));        

        room.add(new BathRoom(wall,new Ceiling("Cement","Purple"),new Floor("Marble")));        

        House house = new House(room);
        house.getHouseDetails();

    }

}
\$\endgroup\$
6
  • 1
    \$\begingroup\$ It depends on what you're trying to model. I think a class for each type of furniture is possibly too deep. Assuming you're creating a room layout, I'd probably create a Furniture class that stores the size of the furniture piece and has a furniture type variable. That way, you can more easily add furniture types. \$\endgroup\$ Commented May 17, 2020 at 12:43
  • \$\begingroup\$ Are you suggesting this -> private Furniture furniture; //Furniture class public class Furniture{ private String sofaType; private String chairType; private String tableType; private int numOfSofa; private int numOfChair; private int numOfTable; } \$\endgroup\$ Commented May 17, 2020 at 13:57
  • \$\begingroup\$ No, that's not a good class either. Count the number of instances of Furniture where type equals sofa. Count the number of instances of Furniture where type equals chair. And o on. \$\endgroup\$ Commented May 17, 2020 at 15:25
  • 1
    \$\begingroup\$ Could you give me the purpose of your Code - what do you want to achive with this Code? \$\endgroup\$ Commented May 18, 2020 at 6:22
  • 3
    \$\begingroup\$ Classes are usually created as a common denominator for things that have something in common. A room is a class, but a bedroom, bathroom, living room, etc. are not. They are instances of a room class. And this approach has the big advantage, that it does not limit the world to some artifical constraints. And now, I'll take my TV to the bathroom and watch some shows in the bathtub. (Excellent blog about this: ericlippert.com/2015/04/27/wizards-and-warriors-part-one) \$\endgroup\$
    – mtj
    Commented May 18, 2020 at 10:09

1 Answer 1

1
\$\begingroup\$

What you want is a Furniture class:

public abstract class AbstractFurniture {
    protected String color;
    protected String make;
    protected String type;

    protected AbstractFurniture(String type, String make, String color) {
        super();

        this.type = type;
        this.make = make;
        this.color = color;
    }

    // Getters go here.
    // toString with getClass().getSimpleName() goes here.
}

From that, you can derive your other classes:

public class Sofa extends AbstractFurniture { ... }
public class Tv extends AbstractFurniture { ... }
public class Chair extends AbstractFurniture { ... }
// ...

You might want to have a Room interface which is implemented by AbstractRoom, though.

That will allow you to manage furniture as furniture, and not as a collection of TVs, chairs, etc..

public abstract class AbstractRoom {
    // ...
    protected List<AbstractFurniture> furniture = null;

    protected AbstractRoom(Wall wall, Ceiling ceiling, Floor floor, AbstractFurniture... furniture) {
        super();

        // ...
        // TODO Check furniture for null first.
        this.furniture = Arrays.asList(furniture);
    }
}

Which will allow you to write code like:

AbstractRoom room = new Bedroom(
        someWall,
        someCeiling,
        someFloor,
        smallTv,
        bigBed,
        smallSofa,
        someChair,
        someChair);

The abstract classes also allow you to have code like the rendering of the room in the abstract base class, so you don't need to duplicate it.


Consider whether your classes need to be immutable, and if they don't need to, you can use a fluent API to make it easier to use instead.

House house = new House()
        .addRoom(bedRoom)
        .addRoom(livingRoom)
        .addRoom(drawingRoom);

getHouseDetails and getRoomDetails are bad names, as they actually don't get anything, but instead write to stdout.


If you want to get extra fancy, Rooms and House are only data holders, and you have a separate HouseRenderer:

public interface HouseRenderer {
    public void renderHouse(House house);
}

public class StdOutStringRenderer implements HouseRenderer {
    @Override
    public void renderHouse(House house) {
        // Code goes here.
    }
}

That would allow you to separate data from presentation, which is always a good idea.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Class structure for furniture will not work. In general, representing real world as a class hierarchy never works because the world is much too complex (how about a TV with integrated DVD-player or a pull-out sofa?) You need a simple Furniture class that has a configurable list of capabilities. \$\endgroup\$ Commented May 18, 2020 at 9:38
  • 1
    \$\begingroup\$ ... and whenever you introduce a restriction in a subclass, you break the Liskov substition principle. \$\endgroup\$
    – mtj
    Commented May 18, 2020 at 10:16
  • \$\begingroup\$ Here it will work fine. Of course something like an Entity/Component system might be better suited, but that's absolute overkill for this description/exercise...and does nothing for OP to learn a little more OOP. \$\endgroup\$
    – Bobby
    Commented May 18, 2020 at 16:12
  • \$\begingroup\$ But feel free to whip up your won solutions based on an ECS, I haven't really worked with one so far, so I'm always curios to see examples. \$\endgroup\$
    – Bobby
    Commented May 18, 2020 at 16:13
  • \$\begingroup\$ Thank you everyone for pitching in and giving me link to useful blogs and sharing their version of my problem. I am trying to solidify my understanding in OOPs before I move to other concepts. This is my 10th try in Java, wonder why I was never able to join the concept pieces together. WIsh me luck. \$\endgroup\$ Commented May 29, 2020 at 6:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.