Java OOP issue - Related to Interface/Abstract Classes - java

I'm stuck with a Java OOP problem. I have come up with some toy code to explain the problem. Here are my classes -
Class 1 - Car.java
public class Car {
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo("Car", 4, problem); //4 is number of wheels
}
//bunch of other methods
}
Class 2 - Truck.java
public class Truck {
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo("Truck", 6, problem);
}
//bunch of other methods
}
Class 3 - ReportUtil.java
public class ReportUtil {
public static void reportVehicleInfo(String name, int wheels, String problem){
System.out.println(String.format("%s %s %s", name, wheels, problem));
}
}
Class 4 - Test.java
public class Test {
public static void main(String[] args) {
Car c = new Car();
c.reportProblem("puncture");
Truck t = new Truck();
t.reportProblem("engine missing");
}
}
I want to abstract the "reportProblem" method implementation in "Car" and "Truck" to a parent class. This is what I did -
Class 1 - Vehicle.java
public abstract class Vehicle {
public String mName;
public int mNumWheels;
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo(mName, mNumWheels, problem);
}
public void setName(String name){
mName = name;
}
public void setNumWheels(int numWheels){
mNumWheels=numWheels;
}
}
Class 2 - Car.java
public class Car extends Vehicle {
//bunch of other methods
}
Class 3 - Truck.java
public class Truck extends Vehicle {
//bunch of other methods
}
Class 4 - ReportUtil.java (No change made to this class).
public class ReportUtil {
public static void reportVehicleInfo(String name, int wheels, String problem){
System.out.println(String.format("%s %s %s", name, wheels, problem));
}
}
Class 5 - Test.java
public class Test {
public static void main(String[] args) {
Car c = new Car();
c.setName("Car"); //NOTE : Can be missed!
c.setNumWheels(4); //NOTE : Can be missed!
c.reportProblem("puncture");
Truck t = new Truck();
t.setName("Truck"); //NOTE : Can be missed!
t.setNumWheels(6); //NOTE : Can be missed!
t.reportProblem("engine missing");
}
}
This achieves what I want (I have abstracted the implementation of "reportProblem"). But I know this is not the best way to do it. One reason is that the "reportProblem" method should not be called without calling "setName" and "setNumWheels" methods. Otherwise 'null' will be passed. Is there a way of enforcing, using some OOP technique, the two methods calls (setName and setNumWheels) BEFORE reportProblem is called?
I hope I have made myself clear. If I am not, just let me know how you would have done it so that I can learn from it.

Yes, make name and numWheels final and assign then in the constructor. So...
Class 1 - Vehicle.java
public abstract class Vehicle {
public final String mName;
public final int mNumWheels;
protected Vehicle(String name, int numWheels){
this.mName = name;
this.mNumWheels = numWheels;
}
public void reportProblem(String problem){
ReportUtil.reportVehicleInfo(mName, mNumWheels, problem);
}
...
}
Class 2 - Car.java
public class Car extends Vehicle {
public Car(){
super("Car", 4);
}
//bunch of other methods
}
Class 3 - Truck.java
public class Truck extends Vehicle {
public Truck(){
super("Truck", 6);
}
//bunch of other methods
}
Also, public fields are not good OO practice, because they expose details of your class' implementation that could be modified by users of the class. Those fields should be private. If the clients of the class need to know about them (or change them), then you should allow public getter (or setter) methods.

If you want to set the fields "required", you can set them as parameters in Truck/Car constructors and not provide a default constructor for these classes.

If members are essentials for an object's state/functionality, put them as part of a constructor, so it is not possible to create an object (and call the method of concern) without providing proper values for these members.
But you should not also provide a no-args constructor.
If there are too many parameters needed consider looking into the Builder idion

In addition to #Tony's answer (+1) if you have to use bean notation (default constructor and setters) and still do not want to allow using any business methods before the object is initialized you can do the following.
Define abstract method checkInitalized() in your Vehicle class. Implement this methods for your Car and Truck. BTW this method will probably have default implementation in Vehicle. In this case do not forget to call super from its overridden versions.
checkInitalized() should throw exception (e.g. IllegalStateException) if not all required fields are initialized.
Now call this method in the beginning of each business method. This will prevent you from using object that is not initialized yet.
This technique is a little bit verbose. Probably using wrapper pattern or AOP (e.g. AspectJ) may be useful here.

Related

Instance variables inside an Abstract Class ****Eclipse malfunctioned, this question is pointless****

So in a challenge in class, we had to use a public abstract Class Cycle as the parent class and create subclasses off of it. I used Unicycle Class as an example.
My professor refuses to let me put Color color as protected. He wants it private. He said the way that I can get the privacy issue worked out was by implementing the getter and setter for color. Initially they were set as abstract Color getColor() and abstract void setColor(Color color) but I tried implementing them inside the abstract class by making them public and giving them the method body.
The test in the code is:
cycle.setColor(Color.RED);
assertEquals(Color.RED, cycle.getColor());
I continue to get the error message,
The field Cycle.color is not visible
I know it works with protected but I have to use private.
Anyone have any hints they can throw at me here? I am going nuts with all of my research and failed trials.
public abstract class Cycle
{
//Declare instance variables
private String make;
private Color color;
//Create a constructor that only contains an argument for make
public Cycle(String make)
{
this.make = make;
}
//Create a constructor that contains an argument for make and color
public Cycle(String make, Color color)
{
this.make = make;
this.color = color;
}
//Create getter and setter methods
abstract int getNumberOfWheels();
//*********Was abstract Color getColor();
public Color getColor()
{
return color;
}
//*********Was abstract void setColor(Color color);
public void setColor(Color color)
{
this.color = color;
}
final String getMake()
{
//return the make of the object
return make;
}
Unicycle Class
public class Unicycle extends Cycle
{
//Create a constructor that only holds the argument make
public Unicycle(String make)
{
//Call on the super (parent) class to create the object with arguments
super(make);
}
public Unicycle(String make, Color color)
{
super(make, color);
}
//Create a method to get the number of wheels and return 1 since a unicycle only has 1 wheel
public int getNumberOfWheels()
{
return 1;
}
}
color is not visible to sub-classes since color is private in Cycle, so having a getter/setter in the Unicycle class results in a compilation issue.
Cycle already defines a getter/setter for color, and Unicycle is-a Cyle, so there's no need to attempt to override the getter/setter in sub-classes.
Remember that any public (or protected) method defined in a base class is available to sub-classes. This is one of the benefits of using inheritance.
My professor refuses to let me put Color color as protected. He wants
it private. He said the way that I can get the privacy issue worked
out was by implementing the getter and setter for color.
In case you were wondering if he is being difficult, I can tell you that he is trying to teach you a very important concept of Object-Oriented Programming. And that is limiting the scope of your variables in this case. You don't EVER want to give direct access to the data members of a class unless they are CONSTANTS. There are a few reasons for it, one of which is in case you need to add preliminary steps in the future before returning the value (i.e. return a value from an alternate source).
Now, you have something like this:
public abstract class Parent {
private String something;
protected Parent() {
something = "N/A";
}
protected String getSomething () {
return something;
}
protected void setSomething (String something) {
this.something = something;
}
}
public class Child extends Parent {
// bad use of override
#Override
public void setSomething (String something) {
super.setSomething(something);
}
// bad use of override
#Override
public String getSomething() {
return something;
}
public static void main (String[] args) {
Child child = new Child();
child.setSomething("New value");
System.out.println(child.getSomething());
}
}
public class Unrelated {
public static void main (String[] args) {
Parent child = new Child();
child.setSomething("Foo");
System.out.println(child.getSomething());
}
}
This works.... The field in the abstract class is private. Therefore, it is blocked from direct manipulation. The child classes can override a protected method of the abstract (parent) class and make it public for unrelated classes to call freely. I included a main method in both the child class and the unrelated class to illustrate this point.
The reason why the override is bad is because it doesn't do anything... HOWEVER, protected methods are restricted to be called outside the package or by classes unrelated to the class declaring the protected method. Therefore, if the unrelated class was outside of the package, it would not be able to call these protected methods. THEREFORE, you must override them by the child classes and make them public. THAT SAID, if this is the case, you could argue that the best thing is to make the protected method public in the parent class and avoid forcing implementing classes to override protected methods just for this reason.

Copy an object that contains a super class of another object

I would like to create a copy of an object that contains a super class of another object. In this example I want to make a copy of the Box that contains a Toy. But all kind of toys can be in the box. What would be the best way to create the copy constructor in Toy?
class Box {
Toy toy;
public Box(Toy toy) {
this.toy = toy;
}
public Box(Box box) {
this.toy = new Toy(box.getToy());
}
}
abstract class Toy {
public Toy(String name) {
// ...
}
}
class Car extends Toy {
public Car(String name) {
super(name);
// ...
}
}
class Puppet extends Toy {
public Puppet(String name) {
super(name);
// ...
}
}
I don't really have an idea how to approach this problem.
Make Toy have an abstract method copy() with return type Toy. Then you will be forced to override this in Car and Puppet. In the copy constructor for Box you can use box.getToy().copy().
You can override the clone method of each Toy's subclass and then :
public Box(Box box) {
this.toy = (Toy) box.getToy().clone();
}
Alternatively, if you have a constant number of types of toy, you can use an enumeration instead of a class.
i think this structure can help you to have an idea,in this case we pass an Object toy using Box Constructor to SuperClass(Toy) and in Toy Class we have a Constructor to Accept an Object from Toy Class then it's call getInstance Method for Initialize toy object(just for example).
class Box extends Toy
{
public Box(Toy toy)
{
super(toy);
}
}
Class Toy
{
private static Toy toys = new Toy();
Toy(){}
Toy(Toy toy)
{
toy = Toy.getInstance();
}
public static Toy getInstance()
{
return toys;
}
}
and either,if you don't want other Classes(sub class) to don't see a specified methods and attributes just make them private,and if you want sub classes haven't access to set and get methods too,make them private only!

Super class which uses the values from children

I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}

Derived Constructor

In the following code:
import java.io.*;
public class MyClass1
{
MyClass1()
{
System.out.println("base class");
}
public void print()
{
System.out.println("base print");
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
System.out.println("child class");
}
public void print()
{
System.out.println("child print");
}
}
Why is it that when I create an instance of type ChildClass the constructor of the base class is also executed??
Because your child class extends the base class - it's an instance of the base class and has all of the same fields and variables, etc. Thus the base class must also be instantiated.
For a concrete example, imagine your base class had the following in:
public class Base
{
final private int id;
public Base()
{
this(-1);
}
public Base(int id)
{
this.id = id;
}
public getId()
{
return id;
}
}
A final variable is guaranteed to be instantiated when the class is constructed. Your child class will have an id field (even if it cannot access it directly with child methods), and since this field is private you cannot possible instantiate it with the child constructor - so a base class constructor must be called.
Bear in mind that this isn't solely an issue with final variables, nor is it unique to any particular features you may use - since your child class is a base class, it needs to be properly instantiated as one.
Because that's what's supposed to happen :-)
Your derived class uses the base class as a foundation. In OO speak it is-a base class. That base class also needs to initialise itself, and consequently its constructor must be called.
It's not obvious from your example, but it will make more sense if you give your base class some (protected) members. Initialise them in the base constructor, and consequently they will have the expected values when viewed from your derived class upon construction.
See below. The field value is visible in the child class. What would you expect as the initialised value ?
public class MyClass1
{
protected int value;
MyClass1()
{
System.out.println("base class");
this.value = 42;
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
// what would you expect 'value' to be here ?
System.out.println("child class " + value);
}
}
Because compiler by default add super() constructor in the child class constructor if it is not specified . Every Constructor Should have either this() in case of without inheritance or super() method when ever there is an inheritance . To illustrate it i have taken this example .
public class Vehicle {
protected int wheels;
protected int lights;
Vehicle(){
System.out.println("Vehicle Class Constructor");
this.wheels=4;
this.lights=2;
}
}
Vehicle is the parent class
class Car extends Vehicle {
public Car(){
#Compiler add the super() constructor by default
System.out.println("Car class constructor");
}
}
Car is the Child class
public class TestCar {
public static void main(String args[]){
Car c = new Car();
System.out.println("Wheels" + c.wheels);
System.out.println("Lights" + c.lights);
}
}
In above code snippet When i compile the TestCar.java file during the Compile time the compiler looks for the Car constructor and checks whether Car class has any parent as soon as it checks that Car class extends the parent class Vehicle , it checks whether user had provided super() in inheritance tree . if not it adds one .
Hope this helps !

Java overloading vs overriding

Hi I just want to make sure I have these concepts right. Overloading in java means that you can have a constructor or a method with different number of arguments or different data types. i.e
public void setValue(){
this.value = 0;
}
public void setValue(int v){
this.value = v;
}
How about this method? Would it still be considered overloading since it's returning a different data type?
public int setValue(){
return this.value;
}
Second question is: what is overriding
in java? Does it relate to inheritance. Let's I have the following:
public class Vehicle{
double basePrice = 20000;
//constructor defined
public double getPrice(){
return basePrice;
}
}
public class Truck extends Vehicle{
double truckPrice = 14000;
//constructor defined
public double getPrice(){
return truckPrice;
}
}
So now let's say I have the following
Truck truck = new Truck();
if I call
truck.super.getPrice()
this would return the price from the Vehicle class, 20,000
if I call
truck.getPrice()
this would return the price in the truck class, 14,000
Is my knowledge correct for both questions?
You are basically correct. Overloading is having multiple methods in a single class where the method has the same name. However, the return value is not seen as part of the signature of the method. Thus, you cannot overload a method by changing only the return value. You cannot have the following code, from your example:
public void setValue() {
this.value = 0;
}
public int setValue() {
return this.value;
}
This will fail to compile.
As Rob identified, I believe you mean overriding, and you have that correct. Note with overriding, you cannot change the return type. As of Java 5, you can return a derived type of what the base class method returned. Before Java 5, it must be the identical type. That is, you cannot do the below until Java 5 and later:
public class AnimalNoise {}
public class Miaw extends AnimalNoise {}
public class Animal {
public AnimalNoise makeNoise() {
return new AnimalNoise();
}
}
public class Cat extends Animal {
public Miaw makeNoise() {
return new Miaw ();
}
}
However, even in Java 5 and later, you cannot do the following:
public class Animal {
public String makeNoise() {
return "silence";
}
}
public class Cat extends Animal {
public Miaw makeNoise() {
return new Miaw ();
}
}
public class Miaw {}
Finally, a big difference between overloading and overriding that is often overlooked is that overloading is decided at compile time and overriding is decided at runtime. This catches many people by surprise when they expect overloading to be decided at runtime.
Correct; overloading is providing multiple signatures for the same method.
Overriding, which is what I think you mean by "overwriting" is the act of providing a different implementation of a method inherited from a base type, and is basically the point of polymorphism by inheritance, i.e.
public class Bicycle implements Vehicle {
public void drive() { ... }
}
public class Motorcycle extends Bicycle {
public void drive() {
// Do motorcycle-specific driving here, overriding Bicycle.drive()
// (we can still call the base method if it's useful to us here)
}
}
what you have described is correct.
For more clarification take a look at polymorphism concept. The Wikipedia has a good article
http://en.wikipedia.org/wiki/Polymorphism#Computing
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

Categories