I'm not really sure how to describe this pattern that i want, but I would like something like this:
public abstract class Parent {
protected abstract boolean foo = false; //this doesn't compile
}
public class Child1 extends Parent {
protected boolean foo = true;
}
how do i do this?
Imagine i have 1 Parent class, but like 20 Child classes. for the vast majority of the children, the foo should be false. However, Child1 (and a few others) is the weird one with foo = true;.
what is the most proper OO Design and yet code effecient way to do this?
You can do this with a constructor or two:
public abstract class Parent {
protected boolean foo;
protected Parent() {
this(false); // initialize foo to default value
}
protected Parent(boolean fooValue) {
this.foo = fooValue;
}
}
public class Child1 extends Parent {
public Child1() {
super(true);
}
}
public class Child2 extends Parent {
// no explicit super(boolean) call in c'tor gives foo the default value
}
First, instance variables cannot be abstract, only methods can.
To have overriding behavior, you need methods. I would define a method, say, isFoo in Parent that is defined to return false. No subclasses would need to override it, except for the "weird one"(s), which can override it to return true.
Alternatively, you can have a subclass of Parent called WeirdOne (doesn't have to be that name of course). The only thing it does is override isFoo to return true. Then Child1 and any other "weird" classes subclass WeirdOne. This way, it's only overridden in one place.
I think you need to do like this
public abstract class Parent {
protected boolean check = false;
}
public class Child extends Parent
{
public void method()
{
this.check=true;
}
}
// You can put it in constructor also
If you want to extend the Parent class using Child1 class, you have to type:
public class Child1 extends Parent {
}
About the foo parameter, you can't set it abstract since is not a function (that is, only functions can be declared abstract). You can, however, override it in subclasses.
public abstract class Parent {
protected boolean foo = false;
}
public class Child1 extends Parent {
#Override
protected boolean foo = true;
}
Don't use a field then. Look at this combination of classes:
public abstract class Vehicle {
public abstract boolean isAerial();
}
public abstract Flyer extends Vehicle {
#Override
public final boolean isAerial() {
return true;
}
}
// Add Airplane, Helicopter, Dirigible, Rocket, etc.
public abstract Terrestrial extends Vehicle {
#Override
public final boolean isAerial() {
return false;
}
}
// Add Car, Truck, Boat, Bicycle, etc.
Related
I have three classes. I want to execute the CodeBlock2 in the Parent class's execute method conditionally based off of a flag I would be setting while calling this method through MyChild class.
For the legacy purposes, modifying the signature of the execute method in Parent class to have an extra boolean argument is not possible.
Q1. In CPP, I have used lambda functions to achieve similar effects; which in my experience, involved a lot of code modifications all across the package wherein equivalent of Parent class was used. I'd refrain from such given the criticality and coverage of my change. Does Java have some similar or easier way do achieve this?
Q2. I think using instance variable with a flag in the Parent class would also be possible, maybe not as elegant. Could someone chime in on this solution as well?
I would really appreciate your opinions. There are some related but not quite similar questions 1, 2.
public abstract class Parent extends GrandParent
{
#override
public void execute(String A)
{
// CodeBlock1
// CodeBlock2 // I wanna put this under if condition based on a flag in MyChild
// CodeBlock3
}
}
public class Child extends Parent
{
#override
protected boolean someMethod()
{
// code
}
}
public class MyChild extends GrandParent
{
#override
public boolean execute(String A)
{
String B = "123";
child.execute(B);
// child.execute(B, true); // what I wanna do
}
private Child child;
}
If you can extract CodeBlock2 into a separate method in the Parent class, the below would work:
public abstract class Parent extends GrandParent
{
#Override
public void execute(String A)
{
// CodeBlock1
codeBlock2(); // I wanna put this under if condition based on a flag in MyChild
// CodeBlock3
}
protected void codeBlock2() {
// CodeBlock2
}
}
public class MyChild extends Parent
{
#Override
protected void codeBlock2() {
if(condition) {
super.codeBlock2();
}
}
}
You can not change the method signature of the parent's method from child,
you can define a boolean flag in the parent with access modifier protected and change
in the child and calling the parent method using super.execute(A)
public abstract class Parent extends GrandParent {
protected boolean enableCodeBlock2;
#override
public void execute(String A) {
// CodeBlock1
if (enableCodeBlock2){
// CodeBlock2 // I wanna put this under if condition based on a flag in MyChild
}
// CodeBlock3
}
}
, And in the child
public class Child extends Parent {
#override
public void execute(String A) {
enableCodeBlock2 = true;
super.execute(A);
}
}
I am in a situation as follows.
I have an interface A which is inherited by class B,C,D (B,C,D implements A).
public interface A{
public String someMethod();
}
class B implements A{
ObjectType1 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
}
class C implements A{
ObjectType2 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
class D implements A{
ObjectType3 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
As you can see all method implementations are the same. So I am duplicating code. My plan was to move the method to A and make A an abstract class. But the problem is my method depends on the model field. So what would be my options to make this code better?
bdw class A,B,C extends and implements other classes too.
EDIT
modification in code. check field
I don't see any problem related to the model field transforming the interface A into an abstract class.
There is no need to reimplement the method in the subclasses if it is the same, unless you want to change its behavior (override it).
public abstract class A {
// Make it protected so it can accessible by subclasses
protected Object model;
// Common behavior that will be inherited by subclasses
public String someMethod() {
if (model instanceof X) {
return "x";
} else {
return "not x";
}
}
}
public class B extends A {
// Subclasses may access superclasses fields if protected or public.
public void someOtherMethod() {
System.out.println(super.model.toString());
}
}
public class C extends A {
// You may wish to override a parent's method behavior
#Override
public String someMethod() {
return "subclass implements it different";
}
}
For your new code example, if you really want to do that in a procedural way you can create an abstract superclass ObjectType and then it will be accessible for the parent as well.
However I wouldn't do that. It seems to me that in doing so is the very opposite of what object orientation tries to solve.
By using a subclass to define the behavior, you wouldn't need to do it in a procedural logic. That's precisely then point of using objects, inheritance and overriding/implementing behavior as needed.
Create a parent class A with said field, and said function. Have the other classes extend A. No need to override them if they function the same.
To deduplicate, you can either make A an abstract class and move the implementation of the method and the field there, or create an abstract class, say E, that implements the interface with that method and field and then have B, C and D extend that class E.
For the more general question of depending on a subclass's field, you can create an abstract method getModel which the subclasses decide how to implement -- by returning a model field or doing something else.
If you are using java 8 you could use default method in interface A, with a getter method for model.
public interface A{
default public String someMethod() {
if(getModel() instanceof X){
System.out.print(true);
}
}
public Object model getModel();
}
Then implement getModel method in all child interfaces.
If you're going to do this you must have model to be of the same (basic) type in all derived objects. If it were of the same type there's a case for putting the model to a base class. Anyway if they are of different derived types you would need to have an accessor to get it.
interface B {
BaseModel getModel();
default public strict doSomething() {
BaseModel m = getModel();
// do something with m
}
}
class D implements B {
DerivedModel model;
public getModel() {
return model;
}
}
If I was given a chance to refactor it, I will follow below approach, leveraging Java 8 Default Methods:
interface A {
default String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return something, for now returning class
return objectType.getClass().toString();
}
}
class B implements A {
#Override
public String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return "Hello"
return "Hello";
}
}
class C implements A {}
class D implements A {}
Usage:
public class Main implements A {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
Main main = new Main();
main.call(b);
main.call(c);
main.call(d);
}
public void call(A clazz) {
ObjectType1 objectType1 = new ObjectType1();
String type = clazz.someMethod(objectType1);
System.out.println(type);
}
}
interface X {
}
class ObjectType1 implements X {
}
Suppose I have a base class with a function foo
public class Base
{
protected static void foo()
{
// ToDo - what is the name of the child class calling me?
}
}
and at least one child class containing a static initialiser that calls foo
public class Child extends Base
{
static
{
foo();
}
}
Is there a way of foo() knowing which child class has called it? I'm presuming there's a reflection technique I can use.
The simplest way is to pass an argument. For example
public class Base {
protected static void foo(Class<?> type) {
if (type == Child.class) {
}
}
}
public class Child extends Base {
static {
foo(Child.class);
}
}
However, if you need to do something that depends on the child class then I recommend looking for a solution that leverages abstract methods and polymorphism.
public Base {
protected static void foo(Base child) {
child.doFoo();
}
protected abstract void doFoo();
}
public Child extends Base {
static {
foo(new Child());
}
#Override
protected void doFoo() {
//do the child specific thing here
}
}
You can get the class by using the getClass method, like:
o.getClass()
also, if you have a class c and you need to check whether o is an instance of c, you can use instanceof, like this:
o instanceof c
Cheers.
I'm building a base/parent class in Java that's going to have several methods for creating the class itself and I'm wondering if there's any way to have the parent class return instances of the child class instead of returning instances of the parent class that then have to be cast to the child?
For example, here's my parent class:
public abstract class SFObject
{
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<SFObject> CreateListFromQuery(Connection connection, String query)
{
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
If I create a child class based on my SFObject class, the two functions in my child class will still return an SFObject (that needs to be cast to my child class type) or a list of SFObjects (that need to be individually cast to my child class type). Is there any way (maybe using Reflections) to have my child class returns instances of itself as itself and not as SFObjects?
What you are describing is known as a covariant return type.
Class A {
A getInstance() { ... }
}
Class B extends A {
#Override
B getInstance() { ... }
}
This has been allowed since Java 1.5.
If you place the child class object inside of the parent object, methods called will run from the child class. But it will look like the parent object on the surface
public class A{
method 1(){//do some stuff}
method 2(){//do some stuff}
}
public class B extends A{
method 1(){super.method 1()
//do some other stuff}
method 2(){super.method 2()
//do some other stuff}
}
public class test{
A a = new B();
//any method called on 'a' will come from the child class
// But 'a' is the parent object
}
Not sure if I really understand your Problem correct because it sounds to me lke this:
class p
{
public static p createParent()
{
return new p();
}
public static c createChild()
{
return new c();
}
}
Of course it doesn't have to be static, just thought of some kind of factory.
Exactly for this functionalities are proposed the factory methods, as you already implemented. In the child class you can change the return type without offending the method declaration. A sample for your case would be something like:
public abstract class SFObject {
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<? extends SFObject> CreateListFromQuery(Connection connection, String query) {
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
class SFObjectChild extends SFObject {
#Override
public SFObjectChild CreateFromDiffObject(DiffObject object) {
SFObjectChild result = new SFObjectChild();
//...
return result;
}
#Override
public List<? extends SFObjectChild> CreateListFromQuery(Connection connection,
String query) {
return null;//..;
}
}
This is acceptable because the return type of the children class is still a kind of (hierarchical speaking) the parent.
Be aware of java code conventions (methods in camel case starting with low, e.g. createFromDiffObject).
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";
}
}