There are many answers to this question here on SO, but I wish to add a small bit of twist in my question. Consider a parent class Parent and it's children Child1 and Child2. Now, let their structure be something like below:
public abstract class Parent {
public abstract String eat();
public abstract String sleep();
public static Parent createInstance (int childType) {
if (childType == 1)
return new Child1();
else
return new Child2();
}
}
public class Child1 extends Parent {
public String eat() {
return "nom-nom";
}
public String sleep() {
return "zzzz...";
}
}
public class Child2 extends Parent {
public String eat() {
return "gulp-gulp";
}
public String sleep() {
return "ZzZz...";
}
}
Now, my questions are:
Am I doing something wrong from pure OOP standpoint, by calling the child classes from the parent class?
Can the above approach be called as an example for strategy design pattern, if I use it in the following way?
// In some random class:
public String showMeHowYouEat (int childType) {
Parent foo = Parent.createInstance(childType);
return foo.eat();
}
public String showMeHowYouSleep (int childType) {
Parent foo = Parent.createInstance(childType);
return foo.sleep();
}
Note : I've selected the above approach of creating child class instances from parent class is because I do not wish to write if-else every time I have to invoke the eat or sleep methods based on the childType.
My main intention behind asking this question was to simply understand if I'm breaking some rules of OOP paradigm by creating an instance of child from the parent class based on some input. And if I'm doing so, then what could be a better alternative to the above mentioned approach?
You are definitely breaking SRP rule
A class should have only one reason to change.
Your Parent class has definitely more reasons to change because you need to modify it when
API will change
new child implementation will be delivered.
You should extract this part to some Factory class/method outside the Parent class
The second question about Strategy pattern cannot be answered because you are not showing the context in which you are using
int childType = 1;
Parent foo = Parent.createInstance(childType);
Maybe it is part of strategy implementation maybe it's not. It depends on how you are using this in the class containing random method
Related
I have gone through http://www.dofactory.com/net/design-patterns in trying to find out the most efficient to create a design pattern in which "one visible class utilizes many hidden classes" to create a fluent API. Below is the code I currently have:
public class VisibleClass {
Private OrderClass order;
private ReceiptClass receipt;
public VisibleClass makeOrder() {
if (!(order instanceof OrderClass))
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (!(receipt instanceof ReceiptClass))
receipt = new ReceiptClass();
receipt.print();
return this;
}
}
class OrderClass implements IOrder {
public void make() {}
}
class ReceiptClass implements IReceipt {
public void print() {}
}
interface IOrder { void make(); }
interface IReceipt { void print(); }
Here is how I am currently using the API:
public static void main(String[] args) {
VisibleClass x = new VisibleClass();
x.makeOrder().printReceipt();
}
It this a good approach? Can a better approach be used for it?
*EDIT: Also, I should add that the VisibleClass will implement all methods of the hidden classes.
Your approach is quite good. Here some recommendations:
1 Change class member types to their interfaces as for 'Program to an interface, not an implementation' principle:
public class VisibleClass {
private IOrder order;
private IReceipt receipt;
2 Do you really need to check class types in makeOrder and printReceipt methods ? Creating instances after null check seems enough:
public VisibleClass makeOrder() {
if (null == order)
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (null == receipt)
receipt = new ReceiptClass();
receipt.print();
return this;
}
3 This approach is valid until methods of VisibleClass will be called by a single thread. If you're going to place it in a multi-thread program, you should ensure that there are only one instances of OrderClass and ReceiptClass each. There are 3 ways you can follow:
a. Create instaces of OrderClass and ReceiptClass in constructor and make VisibleClass singleton.
b. Make OrderClass and ReceiptClass singleton and remove new lines.
c. Create instances surrounded with synchronized block in makeOrder and printReceipt methods.
one visible class utilizes many hidden classes
don't do that with business classes. Fluent syntax's is great for configuration etc, but not for plain business code.
The reason is that the class itself losses control over it's state which can put it in an inconsistent state (i.e generate faulty results).
There is even a principle called Law of Demeter which is about just that.
If you have a business requirement that a receipt should be printed on a new order you should just return it as a return value.
var receipt = visibleClass.makeOrder();
As for using interfaces for entity/business classes, why do you do that? why would you want to abstract away those? The usually do not have any other dependencies or different types of implementations.
You can try using the Facade Design pattern
Or may be try using a Decorator Pattern
I have an array of objects from one class that I made, which includes both objects of that type and objects that extend the first object. I want to access a variable that the extending object has that the first object does not, once I know that the object I am talking about is the extending one. A simplified example of this is shown below:
public class Parent {
public boolean isChild=false;
}
public class Child extends Parent {
public int i=5;
public Child() {
isChild=true;
}
}
public class main {
public static void main(String[] args) {
Parent x=new Child();
if (x.isChild) {
System.out.println(x.i); //this is what I want to do...
//... but I get an error because Parent doesn't have a variable called i.
}
}
}
So, is there any way for me to get around this? (I looked at making a protected static variable but that didn't seem to be what I wanted because I need multiple copies of it.)
Okay, as for how this is actually being used (which I incorrectly didn't include the first time) I am making my own computer programming language for fun. I have an ArrayList of objects that have been created, and allow users of this language to make their own objects as well as use ones that I have made with both java code and code in my language.
I make strings (aka child) in java and have them extend my wafl_object class (parent). This way they can be carried around in that ArrayList without me having to go around with a different array for every object I make. However, I want to accept a String as a parameter for a different class, and I cannot see its value because it is in an object array and I was treating it like an object. I have now fixed this problem by casting it as a String, once I know that it really is one, and then looking at its value. In this situation, it was easier to just cast it, but in others abstactness may have been more usefull.
Instead of testing the type of the object, use polymorphism:
public abstract class Parent {
public abstract int getValue();
}
public class Child extends Parent {
#Override
public int getValue() {
return 5;
}
}
public static void main(String[] args) {
Parent x = new Child();
System.out.println(x.getValue());
}
Just try something like :
if(x instanceof Child){
System.out.println(((Child)x).i);
}
First of all, isChild can be replaced by using instanceof instead: if (x instanceof Child). Afterwards, you can safely cast x to Child: Child childX = (Child)x. childX then gives you access to x.
Generally, checking for types is frowned upon. Normally you should design your functions such that they accept a type that is general enough to do everything they need to do without having to cast to deriving class types.
You don't need your isChild variable. You can use if (x instanceof Child). But in order to access i, you'll have to case x to Child.
In addition, don't access a member directly. Data members such as i should be private and you should access them by getters.
public class main {
public static void main(String[] args) {
Parent x=new Child();
if (x instanceof Child) {
System.out.println((Child)x.getI());
}
}
}
You can solve this with instanceof and a cast, as described in other answers, but in general it's better to use polymorphism, to define a method that subclasses can override. The exact way to do this will depend on the exact nature of your program, but here's one possibility, where I'm using Employee for Parent and HourlyEmployee for Child (constructors and other logic would need to be filled in):
public class Employee {
private String name;
public String getDescription() {
return name;
}
}
public class HourlyEmployee {
private int wage;
#Override
public String getDescription() {
return super.getDescription() + " [at $" + wage + " per hour]";
}
}
Then the class that uses an Employee wouldn't need to test whether it's an HourlyEmployee; it just calls getDescription, and the method either will or won't include the hourly wage in the result, depending on what class it is.
There's no reason to use parent or use child
public class main {
public static void main(String[] args) {
Parent x=new Child();
if (x.isChild) {
System.out.println(((Child)x).i); //this is what I want to do...
//... but I get an error because Parent doesn't have a variable called i.
}
}
}
First of all, previous answers are correct and around the same point. You MUST let the compiler know that the you want to use (x) as a child and not parent.
So, and sticking with your code sample, the answer is to modify the System.out statement to the following:
System.out.println(((Child)x).getValue());
I have a base class say
class A {
private String name;
private String age;
//setters and getters for same
}
and a child class say
class B extends A {
private String phone;
private String address;
//setters and getters for same
}
now I've an instance of A and besides this I have to set the fields in B as well, so code would be like,
A instanceOfA = gotAFromSomewhere();
B instanceOfB = constructBFrom(instanceOfA);
instanceOfB.setPhone(getPhoneFromSomewhere());
instanceOfB.setAddress(getAddressFromSomewhere());
can I instantiate B with given A, but I don't want to do this way,
B constructBFrom(A instanceOfA) {
final B instanceOfB = new B();
instanceOfB.setName(instanceOfA.getName());
instanceOfB.setPhone(instanceOfA.getAge());
return B;
}
rather what I'd love to have some utility with function which is generic enough to construct object as in,
public class SomeUtility {
public static <T1, T2> T2 constructFrom(T1 instanceOfT1, Class<T2> className) {
T2 instatnceOfT2 = null;
try {
instatnceOfT2 = className.newInstance();
/*
* Identifies the fields in instanceOfT1 which has same name in T2
* and sets only these fields and leaves the other fields as it is.
*/
} catch (InstantiationException | IllegalAccessException e) {
// handle exception
}
return instatnceOfT2;
}
}
so that I can use it as,
B constructBFrom(A instanceOfA) {
return SomeUtility.constructFrom(instanceOfA, B.class);
}
Moreover, use case will not be only limited to parent-child classes, rather this utility function can be used for adapter use cases.
PS- A and B are third party classes I've to use these classes only so I can't do any modifications
in A and B.
The good practice is to have a factory class which "produces" the instances of B.
public class BFactory {
public B createBFromA(A a) { ... }
}
You have to write the code of the factory method as there is no standard way of creating a child class based on its parent class. It's always specific and depends on the logic of your classes.
However, consider if it is really what you need. There are not many smart use cases for instantiating a class based on the instance of its parent. One good example is ArrayList(Collection c) - constructs a specific list ("child") containing the elements of the generic collection ("base").
Actually, for many situation there is a pattern to avoid such strange constructs. I am aware it's probably not applicable to your specific case as you wrote that your Base and Child are 3rd party classes. However your question title was generic enough so I think you may find the following useful.
Create an interface IBase
Let the class Base implement the interface
Use composition instead of inheritance - let Child use Base instead of inheriting it
Let Child implement IBase and delegate all the methods from IBase to the instance of Base
Your code will look like this:
public interface IBase {
String getName();
int getAge();
}
public class Base implements IBase {
private String name;
private int age;
// getters implementing IBase
}
public class Child implements IBase {
// composition:
final private IBase base;
public Child(IBase base) {
this.base = base;
}
// delegation:
public String getName() {
return base.getName();
}
public int getAge() {
return base.getAge();
}
}
After you edited your question, I doubt even stronger that what you want is good. Your question looks more like an attempt of a hack, of violating (or not understanding) the principles of class-based object oriented concept. Sounds to me like someone coming from the JavaScript word and trying to keep the JavaScript programming style and just use a different syntax of Java, instead of adopting a different language philosophy.
Fun-fact: Instantiating a child object with parent object is possible in prototype-based languages, see the example in JavaScript 1.8.5:
var base = {one: 1, two: 2};
var child = Object.create(base);
child.three = 3;
child.one; // 1
child.two; // 2
child.three; // 3
In my opinion the way you want to avoid is very appropriate. There must be a piece of such code somewhere.
If you can't put that method in the target class just put it somewhere else (some factory). You should additionaly make your method static.
Take a look at Factory method pattern.
2nd option would be extending B and place this method as factory static method in that new class. But this solution seems to be more complicated for me. Then you could call NewB.fromA(A). You should be able then use your NewB instead of B then.
You could do it via reflection:
public static void copyFields(Object source, Object target) {
Field[] fieldsSource = source.getClass().getFields();
Field[] fieldsTarget = target.getClass().getFields();
for (Field fieldTarget : fieldsTarget)
{
for (Field fieldSource : fieldsSource)
{
if (fieldTarget.getName().equals(fieldSource.getName()))
{
try
{
fieldTarget.set(target, fieldSource.get(source));
}
catch (SecurityException e)
{
}
catch (IllegalArgumentException e)
{
}
catch (IllegalAccessException e)
{
}
break;
}
}
}
}
*Above code copied from online tutorial
I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}
I've run into a situation in which I was to extend the functionality of a given class, but I'm not sure of the best way to go about this. I started by invoking functionality "upwards" and have now switched to "downwards", but I see issues with both. Let me explain what I mean. First, the "upwards" approach:
public class ParentValidator
{
public void validate() {
// Some code
}
}
public class ChildValidator extends ParentValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
This functions perfectly well, but it requires that I always remember to place super.validate() in my method body or the logic in the parent class(es) won't be executed. In addition, extension in this manner can be considered "unsafe" due to the fact that a child class could actually replace/modify the code defined in the parent class. This is what I call invoking methods "upwards" because I'm invoking methods from higher level classes as I go.
To counter these shortfalls, I decided to make ParentValidator.validate() final and have it invoke a different method. Here's what my code was modified to:
public class ParentValidator
{
public final void validate() {
// Some code
subValidate();
}
protected void subValidate() {}
}
public class ChildValidator extends ParentValidator
{
#Override
public final void subValidate() {
// Some code
subSubValidate();
}
protected void subSubValidate() {}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void subSubBalidate() {
// Some code
subSubSubValidate();
}
protected void subSubSubValidate();
}
This is what I was referring to when I say that I'm calling downwards as each class invokes methods on classes "down" the inheritance chain.
Using this approach, I can be guaranteed that the logic in the parent class(es) will be executed, which I like. However, it doesn't scale well. The more layers of inheritance I have, the uglier it gets. At one level, I think this is very elegant. At two levels, it starts to look shoddy. At three or more, it's hideous.
In addition, just as I had to remember to invoke super.validate() as the first line of any of my children's validate methods, I now have to remember to invoke some "subValidate" method at the end of any of my parent's validate methods, so that didn't seem to get any better.
Is there a better way to do this type of extension that I haven't even touched on. Either of these approaches have some serious flaws and I'm wondering if there's a better design pattern I could be using.
In what you describe as your first approach you are using simple inheritance, your second approach is closer to what the Gang of Four [GoF] called a Template Method Pattern because your parent class is using the so-called Hollywood Principle: "don't call us, we'll call you".
However, you could benefit from declaring the subvalidate() method as abstract in the parent class, and by this, make sure all subclasses are forced to implement it. Then it would be a true template method.
public abstract class ParentValidator
{
public final void validate() {
//some code
subValidate();
}
protected abstract void subValidate() {}
}
Depending on what you are doing there are other patterns that could help you do this in a different manner. For instance, you could use a Strategy Pattern to peform the validations, and by this favoring composition over inheritance, as suggested before, but a consequence is that you will need more validation classes.
public abstract class ParentValidator
{
private final ValidatorStrategy validator;
protected ParentValidator(ValidatorStrategy validator){
this.validator = validator;
}
public final void validate() {
//some code
this.validator.validate();
}
}
Then you can provide specific validation strategies for every type of Validator that you have.
If you want to get the best of both worlds you might considering implementing the solution as a Decorator Pattern where subclasses can extend the functionality of a parent class and still stick to a common interface.
public abstract class ValidatorDecorator implements Validator
{
private final Validator validator;
protected ParentValidator(Validator validator){
this.validator = validator;
}
public final void validate() {
//some code
super.validate(); //still forced to invoke super
this.validator.validate();
}
}
All patterns have consequences and advantages and disadvantages that you must consider carefully.
I'd prefer to 1) program against interfaces, and 2) opt for composition over inheritance. This is how I have done. Some people like it, some do not. It works.
// java pseudocode below, you'll need to work the wrinkles out
/**
* Defines a rule or set of rules under which a instance of T
* is deemed valid or invalid
**/
public interface ValidationRule<T>
{
/**
* #return String describing invalidation condition, or null
* (indicating then that parameter t is valid */
**/
String apply(final T t);
}
/**
* Utility class for enforcing a logical conjunction
* of zero or more validatoin rules on an object.
**/
public final class ValidatorEvaluator
{
/**
* evaluates zero or more validation rules (as a logical
* 'AND') on an instance of type T.
**/
static <T> String apply(final T t, ValidationRule<T> ... rules)
{
for(final ValidationRules<T> v : rules)
{
String msg = v.apply(t);
if( msg != null )
{
return msg; // t is not valid
}
}
return null;
}
}
// arbitrary dummy class that we will test for
// i being a positive number greater than zero
public class MyFoo
{
int i;
public MyFoo(int n){ i = n; }
///
}
public class NonZeroValidatorRule implements ValidatorRule<MyFoo>
{
public String apply(final MyFoo foo)
{
return foo.i == 0 ? "foo.i is zero!" : null;
}
}
// test for being positive using NonZeroValidatorRule and an anonymous
// validator that tests for negatives
String msg = ValidatorEvaluator.apply( new MyFoo(1),
new NonZeroValidatorRule(),
new ValidatorRule<MyFoo>()
{
public String apply(final MyFoo foo)
{
return foo.i < 0 ? "foo.i is negative!" : null;
}
}
);
if( msg == null )
{
\\ yay!
...
}
else
{
\\ nay...
someLogThingie.log("error: myFoo now workie. reason=" + msg );
}
More complex, non-trivial evaluation rules can be implemented this way.
The key here is that you should not use inheritance unless there exists a is-a relationship. Do not use it just to recycle or encapsulate logic. If you still feel you need to use inheritance, then don't go overkill trying to make sure that every subclass executes the validation logic inherited from the superclass. Have implementations of each subclass do an explicit execution on super:
public class ParentValidator
{
public void validate() { // notice that I removed the final you originally had
// Some code
}
}
pubic class ChildValidator extends ParentValidator
{
#Override
public void validate() {
// Some code
super.validate(); // explicit call to inherited validate
// more validation code
}
}
Keep things simple, and don't try to make it impossible or fool-proof. There is a difference between coding defensively (a good practice) and coding against stupid (a futile effort.) Simply lay out coding rules on how to subclass your validators. That is, put the onus on the implementors. If they cannot follow the guidelines, no amount of defensive coding will protect your system against their stupidity. Ergo, keep things clear and simple.
I prefer to using composition over inheritance if your subSubSubValidate is related general functionality. You can extract new class and move it there than you can use it without inheritance in the other classes.
There is also
"Favor 'object composition' over
'class inheritance'." (Gang of Four
1995:20)
maybe a look at the visitor pattern may help you to develop your pattern.
Here are some information on it : http://en.wikipedia.org/wiki/Visitor_pattern