Java Inheritance: Restrict List to Subclass Objects - java

Let's assume I have 3 classes: Car, Convertible and Garage.
Car:
public class Car {
private String name;
private String color;
public Car(String name, String color) {
this.name = name;
this.color = color;
}
//Getters
}
Convertible inherits from Car:
public class Convertible extends Car{
private boolean roof;
public Convertible(String name, String color, boolean roof) {
super(name, color);
this.roof = roof;
}
public boolean isRoof() {
return roof;
}
}
Garage stores a list of Cars:
public class Garage {
private int capacity;
private List<Car> cars = new LinkedList<Car>();
//Setter for capacity
}
How could I create a subclass of Garage called ConvertibleGarage that can only store Convertibles?

You could use a little bit of generics:
public class Garage<T extends Convertible> {
private int capacity;
private List<T> cars = new LinkedList<T>();
public Garage(int capacity) {
this.capacity = capacity;
}
}
This means when you instantiate a Garage you now have to include a parameter type that is a Convertible or child of it.
Garage<Convertible> cGarage = new Garage<>();

Generics will help here.
Make the Garage class generic Garage<T extends Car>, where a T is a car type it can store. Rewrite the cars list to a generic view List<T> as well.
Then, a Garage<Convertible> is going to be your "ConvertibleGarage".

You don't really need to make a second Garage class, you can use Generics :
public class Garage<T extends Car> {
private int capacity;
private List<T> cars;
public Garage() {
this.cars = new LinkedList<>();
}
public static void main(String[] args) {
Garage<Convertible> garConv = new Garage<>();
garConv.cars.add(new Convertible("", "", true));
Garage<Car> garCar = new Garage<>();
garCar.cars.add(new Car("", ""));
}
}
With this only class you can have a garage for car and a one for convertible

As the other answers have explained, you solve your problem by making your Garage class generic - and therefore allowing any instance of Garage to deal with exactly one kind of cars.
But what is missing so far: this is not "an option" to solve your problem - this is simply "the way to go here". Your idea of using inheritance is "plain wrong". Meaning: when people start with object oriented design, they assume that inheritance is the answer to everything. And actually that is not true. You are rather careful about creating an extends relation between two classes.
And especially when talking about containers - classes that "contain" other objects - then generics is your first thought!

Related

Java share common functionality between enums using interfaces

I have a few enums that have the same functionality but contain different constants for organization reasons. They each look like this:
public enum OneEnum {
greenApple(apple, green),
redApple(apple,red);
private final String fruit;
private final String type;
private OneEnum (final String fruit, final String type) {
this.fruit = fruit;
this.type = type;
}
public String getFruit() {
return fruit;
}
public String getType() {
return type;
}
}
The other enums have the same private fields, constructor, and methods and only differ by listed constants. I was wondering how much of this code I can move to a common place such as interface (or abstract class if possible). I am able to create an interface such as:
public interface CommonEnum {
String getFruit();
String getType();
}
but can I do better than that?
You could do something like this:
public interface CommonEnum { ...
public class Holder implements CommonEnum() {
private final String fruit ...
}
public enum OneEnum {
GREEN_APPLE(new Holder(GREEN, APPLE)), ...
private OneEnum(Holder holder) { this.holder = holder };
public getHolder() { return holder };
In other words: if that "combination" of values is the "common thing" that you need in different places, than that should go into its own class.
Of course, the downside of this is: users of your enum would now be violating the Law of Demeter, as in:
Fruit fruit = OneEnum.GREEN_APPLE.getHolder().getFruit();
I don't at all see the point in using an enum for the combination of values at all.
What you have in effect is
public enum Fruit {
APPLE, ORANGE, BANANA //...
}
public enum Color {
RED, GREEN, BLUE // ...
}
and a combination of the two
class ColoredFruit {
public final Fruit fruit;
public final Color color;
public ColoredFruit(Fruit f, Color c) { fruit = f; color = c; }
}
The enums you have are only instances
Collection<ColoredFruit> apples = Arrays.asList(new ColoredFruit(APPLE, RED), new ColoredFruit(APPLE, GREEN));
And if you do feel fancy, add interfaces
interface Fruit {
FruitEnum getFruit();
}
interface Colored {
Color getColor();
}
which ColoredFruit can implement by adding getters.

How can I ensure an argument is a class field (Java)?

I am creating an API that returns a list of Cars. The API user must be able to request that the list be filtered and sorted by a certain attribute (field) of the Cars class. How can I do that?
class Car {
public final String model;
public final String color;
public Car(String m, String c) {
model = m;
color = c;
}
}
class CarListRequest {
public final String sortBy;
public final String filterBy;
public final List<String> filterList;
public CarListRequest(String s, String f, List<String> list) {
sortBy = s;
filterBy = f;
filterList = list;
}
}
Is there a way to restrict, using Java language features, that sortBy and filterBy Strings cannot contain any other values than attributes (fields) of the Car class?
I know that I could use an enum to declare all attributes of Car however, that causes a duplication of Strings which I would like to avoid.
#hmc_jake 's reflection suggestion is quite valid. However, if you want to avoid reflection, you could do it using a class hierarchy:
class CarAttribute {
private String attrib;
public CarAttribute(String att){
attrib = att;
}
// add getters and/or setters for attrib ...
}
class CarModel extends CarAttribute {
}
class CarColor extends CarAttribute {
}
class Car {
public final CarModel model;
public final CarColor color;
public Car(CarModel m, CarColor c) {
model = m;
color = c;
}
}
class CarListRequest {
public final CarAttribute sortBy;
public final CarAttribute filterBy;
public final List<CarAttribute> filterList;
public CarListRequest(CarAttribute s, CarAttribute f, List<CarAttribute> list) {
sortBy = s;
filterBy = f;
filterList = list;
}
}
Using Reflection in Java, it is possible to inspect a class's fields.
When, for example, s is passed in, you can perform a check on the argument like so:
for (Field field : Car.class.getFields()) {
if (field.getName().equalsIgnoreCase(s)) {
Do something here to signal that s
was a valid Field of the Car class.
}
}
Doing this allows you to reflectively inspect the Car class in order to verify that the argument passed in is in-fact a field of that class.
Note, however, that if possible you should go with the enum or class hierarchy as reflection might be a little bit overkill for what you're trying to accomplish.

Java wrapper class subclass of concrete type

Let's say I have a class person as follows:
public class Person {
String name;
int age;
}
and a number of subclasses such as
public class Student extends Person {
// extra fields and methods
}
public class Teacher extends Person {
// extra fields and methods
}
Now, consider that for some application I need to assign an integer id to each person instance, but I don't want to extend the Person interface to add the getId() there and a field to hold the id. A simple solution would be to use a wrapper like:
public class PersonWrapper extends Person {
public PersonWrapper(Person p, int id) { // assign the id and other fields }
public int getId() { return id; }
}
This way the client code still works with the Person interface and a wrapped person can be
treated as a person.
The problem with this approach is that PersonWrapper is a subclass of Person and not Teacher or Student, and such a code won't work:
Teacher t = new PersonWrapper(teacher, 1);
t.giveGrade();
Of course, it's possible to create concrete wrapper types for all subclasses of Person, but I was wondering if there is a more elegant solution. The ideal solution would be something like this:
public class PersonWrapper<T extends Person> extends T
so that any PersonWrapper is a subclass of the type it wraps, but it's not possible in Java and I
suspect such definition may not be possible in any language.
In any case, how can I assign ids to subclasses without changing my client code that works with person and its subclasses, without creating a concrete wrapper for each subclass?
A wrapper does not necessarily need to extend to the class it's wrapping. So, just use PersonWrapper<T extends Person>:
public class PersonWrapper<T extends Person> {
T person;
int id;
public PersonWrapper(T person, int id) {
this.person = person;
this.id = id;
}
//getters and setters...
}
Also, a class can only extend from another class at compile time, so it's not possible that this PersonWrapper could extend from Student and Teacher at the same time, which makes impossible what you're looking for.
The only solution would be creating proxy classes on the fly using a library like cglib. For example, Spring creates proxies for classes when needs to add functionality on the fly to a class e.g. adding transaction management for methods or whole class.
The common solution to this problem is to make Person an interface.
interface Person {
public String getName();
public int getAge();
}
class ActualPerson implements Person {
private final String name;
private final int age;
ActualPerson(String name, int age) {
this.name = name;
this.age = age;
}
#Override
public String getName() {
return name;
}
#Override
public int getAge() {
return age;
}
}
class PersonWithId implements Person {
private final Person person;
private final int id;
PersonWithId(Person person, int id) {
this.person = person;
this.id = id;
}
#Override
public String getName() {
return person.getName();
}
#Override
public int getAge() {
return person.getAge();
}
}
Do not fear lots of code - the time you take writing code is insignificant compared to the time you spend regretting you didn't do it properly in the first place. Old Curmudgeon 2014
You're right that you can't do what you want to do. Assuming that you can't change the concrete classes to be, say, Student extends Person implements Identifiable, your best bet is to treat your wrapper really as a wrapper, and have a getter that returns its different elements:
public class Wrapper<T> {
private final T item;
private final int id;
...
public int getId() { return id }
public T getItem() { return item; }
}
This is a bit cumbersome to use, because you have to do something like wrapper.getItem().giveGrade() instead of just wrapper.giveGrade(). It also means you can't shove the wrapper into a List<Teacher> and then later downcast it to TeacherWrapper -- but that's a bit fragile, and there are often better ways to accomplish what you want. For most cases, this "pure" wrapper approach will do what you want.
Note that I didn't even have T extends Person. If the wrapper class doesn't need to use any Person methods, there's not much to gain from artificially restrict the generic. The call sites will all have the restriction either way. The one difference is that if a call site has a Wrapper<?>, then my code will only let you get the item as an Object, whereas the more restrictive T extends Person will let you get that item as a Person.
I hope I'm not missing something, but it appears to me that the wrapper pattern solves your problem:
public class Person implements IPerson{
String name;
int age;
public static void main(String[] args)
{
Teacher teacherWithID = new Teacher(new PersonWithID(new Person()));
Teacher teacherWithoutID = new Teacher(new Person());
}
}
interface IPerson{}
class Teacher implements IPerson{
public Teacher(IPerson personToBeWrapped){}
}
class Student implements IPerson{
public Student(IPerson personToBeWrapped){}
}
class PersonWithID implements IPerson{
public PersonWithID(IPerson personToBeWrapped){}
}
Whatever type your variable is should be the last wrapper.
The wrapper pattern can be considered to be a mechanic that allows you to "extend" classes at runtime. It's also called the decorator for that reason. You have competing inheritance mechanics in your code. (the built in one and the pattern) The result is that you cannot type your variable.
If you use the pattern exclusively, it works.

How to extend or implement classes? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Picture to show task:
First I am sorry, for my bad to for expressing my mind.
I have such a task, I don't need that you do it for me.
Vehicle is parent class for Sedan (Cause Sedan class is String type).
How to extend or implement Vehicle class with universal class?
I forgot to ask my teacher, but maybe you will know, what means striped pointer to Owner class, and what is that: has a?
P.S. If you need code that I have written already, I will show you.
So this is my parent Vehicle class:
public class Vehicle {
private int vehicleNumber;
protected int fuelTankSize;
protected int maxSpeed;
protected Owner owner;
//1
public Vehicle(int vehicleNumber){
this.vehicleNumber = vehicleNumber;
}
//2
public Vehicle(int vehicleNumber, int fuelTankSize) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
}
//3
public Vehicle(int vehicleNumber, int fuelTankSize, int maxSpeed) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
this.maxSpeed = maxSpeed;
}
//4
public Vehicle(int vehicleNumber, int fuelTankSize, int maxSpeed, Owner owner) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
this.maxSpeed = maxSpeed;
this.owner = owner;
}
//1
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed (int maxSpeed){
this.maxSpeed = maxSpeed;
}
//2
protected int getFuelTankSize(){
return fuelTankSize;
}
protected void setFuelTankSize (int fuelTankSize){
this.fuelTankSize = fuelTankSize;
}
//3
public Owner getOwner(){
return owner;
}
public void setOwner (Owner owner){
this.owner = owner;
}
}
child Sedan with:
public class Sedan extends Vehicle {
private String registrationIndex;{
}
public Sedan (int vehicleNumber, int fuelTankSize, int maxSpeed, String registrationIndex, Owner owner) {
super(vehicleNumber, fuelTankSize, maxSpeed, owner);
this.setRegistrationIndex (registrationIndex);
}
public String getRegistrationIndex (){
return registrationIndex;
}
public void setRegistrationIndex (String registrationIndex) {
this.registrationIndex = registrationIndex;
}
}
second Universal child without an error:
public class Universal extends Vehicle {
private int trunkSize;
public Universal (int vehicleNumber, int fuelTankSize, int maxSpeed, int trunkSize, Owner owner) {
super(vehicleNumber, fuelTankSize, maxSpeed, owner);
this.setTrunkSize (trunkSize);
}
public int getTrunkSize() {
return trunkSize;
}
public void setTrunkSize(int trunkSize) {
this.trunkSize = trunkSize;
}
public void printDescription() {
super.printDescription();
System.out.println("Universalo bagažinės tūris: " + getTrunkSize() + "l.");
}
}
and some misterious (to me) Owner class:
public class Owner {
public String firstName;
public String lastName;
public Owner (String firstName){
this.firstName = firstName;
}
public Owner (String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
}
added VechileTest for testing:
public class VehicleTest {
public static void main(String[] args) {
Vehicle vehicleInf = new Vehicle (1, 45, 260);
Universal universalInf = new Universal(2, 50, 220, 70);
Sedan sedanInf = new Sedan (3, 40, 180, "AVA 123");
vehicleInf.printDescription();
universalInf.printDescription();
sedanInf.printDescription();
}
}
Well, 1st of all I recommend you read a good tutorial / explanation of UML class diagrams, like this here for example.
After you know the basics, it should be easy to translate that into Java code.
I'll give you the code for the Universal class and a start for your Vehicle. The rest you'll have to do on your own.
The class Universal:
public class Universal extends Vehicle {
private int trunkSize;
public int getTrunkSize() {
return this.trunkSize;
}
public void setTrunkSize(int trunkSize) {
this.trunkSize = trunkSize;
}
}
As you can see the first block inside a class box refers to the variables. The - and + indicates the visibility (private for -, public for +).
The next block is about the methods, specifying visibility, return type, method name and parameters (type and name).
The arrow between Universal and Vehicle indicates a inheritance relationship (see in code that Universal extends Vehicle).
So all in all the diagram is a construction plan for your classes; at least for the static part, meaning the relationships and state they can have.
The start of class Vehicle:
public class Vehicle {
private int vehicleNumber;
// the rest here ...
}
Edit:
Well, now that I see your code, you seem to have a few misconceptions:
The Sedan type is not from type String, it is from type Sedan (which extends Vehicle). Just the new member variable in the Sedan type is of type String, does not matter.
To your 1st question: The Vehicle class is the base (parent) class of Sedan. You do not to do anything with it, inheritance is expressed from the child towards the parent, not the other way around. Vehicle should usually be declared abstract (as you cannot create an instance of a generic Vehicle), but this is not in the diagram.
To your 2nd question: The has a relationship is just this. It expressed that one class has another class as it's member (which is redundantely expressed inside the class diagram already), so nothing to do for that.
Additionally your code has a few issues:
I do not see any constructors declared in Vehicle class, those 4 can go.
Your Sedan has a superflous pair of {} after declaration of your registrationIndex variable.
Since your Vehicle has no default constructor, you must call this constructor from your Sedan class (or remove the constructors from Vehicle.
Your Universal class calls the Vehicle constructor with the trunkSize while the Vehicle constructor expects the vehicleNumber there.
Your Vehicle class doesn't have a parameterless constructor, which means that Universal and Sedan must explicitly call one of them (super(...);). You're doing this in Universal (albeit incorrectly as you're passing the trunk size instead of the vehicle number expected by Vehicle's constructor) but not in Sedan.
As for the second question: The two major relations in OOP are is a and has a. The difference can be easily explained like this:
A Sedan is a vehicle
A vehicle has an owner
is a means it inherits some properties of something else, has a means that it has a reference to something else.

Builder Pattern: which variant is preferred? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I was going through Effective Java book , and creating notes for my future reference ,
i came across Builder Pattern.
Well i understood what it is and how its suppose to be used.In the process i created a two example variations of the builder pattern.
I would need help in listing down the differences and the advantage each has?
Well i certainly noticed that , Example 1 exposes less methods , there by less restrictive and
more generic , there by allowing it to be used more flexibly.
Please point out other things i have missed?
Example 1
package item2;
/**
* #author Sudhakar Duraiswamy
*
*/
public class Vehicle {
private String type;
private int wheels;
interface Builder<T>{
public T build();
}
public static class CarBuilder implements Builder<Vehicle>{
private String type;
private int wheels;
CarBuilder createVehicle(){
this.type= "Car";
return this;
}
CarBuilder addWheels(int wheels){
this.wheels = wheels;
return this;
}
public Vehicle build(){
Vehicle v = new Vehicle();
v.type = type;
v.wheels = wheels;
return v;
}
}
public static class TruckBuilder implements Builder<Vehicle>{
private String type;
private int wheels;
TruckBuilder createVehicle(){
this.type= "Truck";
return this;
}
TruckBuilder addWheels(int wheels){
this.wheels = wheels;
return this;
}
public Vehicle build(){
Vehicle v = new Vehicle();
v.type = type;
v.wheels = wheels;
return v;
}
}
public Vehicle(){
}
public static void main(String[] args) {
//This builds a car with 4 wheels
Vehicle car = new Vehicle.CarBuilder().createVehicle().addWheels(4).build();
//THis builds a Truck with 10 wheels
Vehicle truck = new Vehicle.TruckBuilder().createVehicle().addWheels(10).build();
}
}
Example 2
package item2;
/**
* #author Sudhakar Duraiswamy
*
*/
public class Vehicle2 {
private String type;
private int wheels;
interface Builder<T>{
public T build();
public String getType();
public int getWheels() ;
}
public static class CarBuilder implements Builder<Vehicle2>{
private String type;
private int wheels;
public String getType() {
return type;
}
public int getWheels() {
return wheels;
}
CarBuilder createVehicle(){
this.type= "Car";
return this;
}
CarBuilder addWheels(int wheels){
this.wheels = wheels;
return this;
}
public Vehicle2 build(){
return new Vehicle2(this);
}
}
public static class TruckBuilder implements Builder<Vehicle2>{
private String type;
private int wheels;
public String getType() {
return type;
}
public int getWheels() {
return wheels;
}
TruckBuilder createVehicle(){
this.type= "Truck";
return this;
}
TruckBuilder addWheels(int wheels){
this.wheels = wheels;
return this;
}
public Vehicle2 build(){
return new Vehicle2(this);
}
}
public Vehicle2(Builder<? extends Vehicle2> builder){
Vehicle2 v = new Vehicle2();
v.type = builder.getType();
v.wheels = builder.getWheels();
}
public Vehicle2(){
}
public static void main(String[] args) {
//This builds a car with 4 wheels
Vehicle2 car = new Vehicle2.CarBuilder().createVehicle().addWheels(4).build();
//THis builds a Truck with 10 wheels
Vehicle2 truck = new Vehicle2.TruckBuilder().createVehicle().addWheels(10).build();
}
}
None of the above.
The first one doesn't allow building an immutable Vehicle, which is often why the Builder pattern is used.
The second example is a variation of the first one which allows getting information from the builder using additional getter methods. But those those methods aren't used anywhere, except in the Vehicle constructor, which has access to the builder fields directly. I don't see the point in adding them.
I see two more important things to improve:
The two builder types do exactly the same thing. There's no need for two types. A single one is sufficient.
What the createVehicle() method does should be done by the builder constructor. If you construct a CarBuilder, it's obviously to build a car, so the type of the vehicle should be set as soon as the builder is constructed. Here's how I would write it:
.
public final class Vehicle {
private final String type;
private final int wheels;
private Vehicle(Builder builder) {
this.type = builder.type;
this.wheels = builder.wheels;
}
public static Builder carBuilder() {
return new Builder("car");
}
public static Builder truckBuilder() {
return new Builder("truck");
}
public static class Builder {
private final String type;
private int wheels;
private Builder(String type) {
this.type = type;
}
public Builder addWheels(int wheels){
this.wheels = wheels;
return this;
}
public Vehicle build() {
return new Vehicle(this);
}
}
public static void main(String[] args) {
Vehicle car = Vehicle.carBuilder().addWheels(4).build();
Vehicle truck = Vehicle.truckBuilder().addWheels(10).build();
}
}
There is a third variant too, with less code:
Instead of having their own instance fields the builders could also mutate the state of Vehicle. Inner classes can write private members of their outer class:
class Vehicle {
private int wheels;
private Vehicle() {}
public static class Builder {
private boolean building = true;
private Vehicle vehicle = new Vehicle();
public Builder buildWheels(int wheels) {
if(!this.building) throw new IllegalStateException();
this.vehicle.wheels = wheels;
return this;
}
public Vehicle build() {
this.building = false;
return this.vehicle;
}
}
}
Since the fields are private and you allow it to be build only once (building flag), built Vehicle instances are still immutable to consumers even though the fields cannot be final anymore (no more realio-trulio immutability, see Eric's blog article which is on C# but the concepts are similar).
You need to be more careful as non-final fields do not have to be initialized during object construction (enforced by the compiler) and you must check the building state carefully. You do however save a full extra-copy of all instance fields. In general, this is useful if you have a rather large set of instance variables that are built with rather few methods, where each method builds a few fields at once.
I know this does not point out any advantages or drawbacks of your approaches. However, this approach can save a lot of extra code if you do not need the fields to be final.

Categories