Suppose I have this hierarchy of classes
class Parent {
protected List<Object> things = new List<Object>;
public Parent() {
things.addAll(declareThings());
}
public List<Object> declareThings() {
// things declaration
}
}
class Child extends Parent {
public List<Object> declareThings() {
// additional things declaration
}
}
class GrandChild extends Child {
public List<Object> declarThings() {
// addtional things
}
}
I would like that creating an instance of say GrandChild, I get all the declared things in the hierarchy. Is it possible to implement such behaviour?
For each subclass, add a constructor where the first instruction is super();.
Related
This might (most certainly will) sound stupid, but I am stuck and I cant find a proper solution to my problem.
I have a superclass and two sub classes extend it. On the parent class based on a condition I want to call the method from either of the two classes. This is inside a loop, so instead of doing the same check I decided to do the check once, create an object from the super class and then change the object to either one of the two sub classes. i.e.
public class Parent{
public void method() {
Parent object=new Parent();
if(a==b) {
object=new Child_A();
}else {
object=new Child_B();
}
for() {
object.method();
}
}
public void method() {
//empty method. need it just to compile
}
}
public class Child_A extends Parent{
public void method() {
//do something useful
}
}
public class Child_A extends Parent{
public void method() {
//do something useful
}
}
I had to write the Parent.method(), cos otherwise the compile would complain that there is no method() method on class Parent.
So with this, the method called is not one of the children,but the parents method.
I have read that objects need to be assigned directly to the class, like Childen_A object=new Childen_A. The thing is that I would like to use the same command for both cases (object.method()) no matter which class it refers to. Strange thing is that during debug, i see that object is of type Child_A, nevertheless the super method is called.
I know that the solution would be to create two different objects, one for each sub class, but that would make my code a bit more ugly and i would have to use the if statement inside the loop.So the correct way of doing it must be
public void method() {
for() {
if(a=b) {
Child_A object=new Child_A();
object.method();
}else {
Child_B() object=new Child_B();
object.method();
}
}
}
Is there a way to avoid the if statement inside the loop? Thanks
Your code should be
public class Parent {
public void method() {
}
// OR
public abstract void method(); // and make the class abstract as well
}
public class Child_A extends Parent {
#Override
public void method() {
//do something useful
}
}
// same with Child_B
The following is a popular use case involving abstract method and overridding.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
abstract class Parent {
abstract void method();
}
class Child_A extends Parent {
#override
void method() {
do the task for Child_A;
}
}
class Child_B extends Parent {
#override
void method() {
do the task for Child_B;
}
}
It seems that we can always achieve the same thing by defining a generic method in the superclass, which uses the instanceof keyword to determine the subclass and performs the corresponding task for the subclass.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
class Parent {
void method() {
if (this instanceof Child_A) {
do the task for Child_A;
}
else if (this instanceof Child_B) {
do the task for Child_B;
}
}
}
class Child_A extends Parent {
}
class Child_B extends Parent {
}
Which code style is better and why?
Because:
you don't want to have to modify the parent class every time you add another subclass
in some circumstances like a library API you may not even know all the subclasses
code that deals with a subclass should be in that subclass, not in the parent.
If you do the latter, your subclasses becomes useless. They don't do anything. I'd like to think of it this way, the parent passed you the ability to do methodA in your own way. However in your case, the parent does everything, meaning you are dependent on your parent forever. Who would want that?
Well aside from that, when you create a new subtype, you'll have to edit also the parent(very absurd), think of what will happen 100 subtypes later. Give your subtypes the power to have their own individuality.
I have an input file (text => TextFileImporter or xml => XmlFileImporter) which contains data with different structures. A structure is described in the Definiton class, so my FileImporter object holds multiple instances of Definition.
A TextFileImporter should hold List<TextDefinition> and a XmlFileImporter should hold List<XmlDefinition>.
Please have a look at the example code:
// Parent classes
abstract class Definition {}
abstract class FileImporter {
protected List<Definition> definitions;
public FileImporter(List<Definition> definitions) {
this.definitions = definitions;
}
public void doSomething() {
// use 'definitions'
}
}
// Text files
class TextDefinition extends Definition {
public void copyLine() {}
}
class TextFileImporter extends FileImporter {
// here should be clear that 'definitions' is of type List<TextDefinition>
// to call 'copyLine()' on its items
}
// XML files
class XmlDefinition extends Definition {
public void copyNode() {}
}
class XmlFileImporter extends FileImporter {
// here should be clear that 'definitions' is of type List<XmlDefinition>
// to call 'copyNode()' on its items
}
As you can see on the basis of the comments I'm not sure how to handle that preferably. Of course I first need constructors. Then, I don't want to cast each item of definitions to the suitable subclass every time just to call a method.
Can I make a reasonable use of generics here? Or is there another solution?
You have to introduce some generics.
// Parent classes
abstract class Definition {}
abstract class FileImporter<T extends Definition> {
protected List<T> definitions;
public FileImporter(List<T> definitions) {
this.definitions = definitions;
}
public void doSomething() {
// use 'definitions'
}
}
// Text files
class TextDefinition extends Definition {
public void copyLine() {}
}
class TextFileImporter extends FileImporter<TextDefinition> {
// here should be clear that 'definitions' is of type List<TextDefinition>
// to call 'copyLine()' on its items
}
// XML files
class XmlDefinition extends Definition {
public void copyNode() {}
}
class XmlFileImporter extends FileImporter<XmlDefinition> {
// here should be clear that 'definitions' is of type List<XmlDefinition>
// to call 'copyNode()' on its items
}
i need to declare a list which should accept only the parent class objects and it should not allow the sub class objects.
parent class:
public class ParentClass {
private String parentAttr;
public String getParentAttr() {
return parentAttr;
}
public void setParentAttr(String parentAttr) {
this.parentAttr = parentAttr;
}
}
Sub class:
public class SubClass1 extends ParentClass {
private String attr1;
public String getAttr1() {
return attr1;
}
public void setAttr1(String attr1) {
this.attr1 = attr1;
}
}
Main class:
public class MainClass {
public static void main(String[] args) {
ParentClass parentClass=new ParentClass();
SubClass1 subClass1 = new SubClass1();
List<ParentClass> list=new ArrayList<ParentClass>(); // modify this declaration such that it should accept only the parent class objs
list.add(parentClass);
list.add(subClass1); // this should not happen. only parent class objects should be added in the list
}
}
I tried using generics as well. but it is not working. is there any way to achieve this in java generics?
You can Implement the List interface and provide your own implementation for the List.add(int index, E element) method and check if the element is instanceof the parent Class and not an instanceof the child Class in your implementation.
You can also extend the ArrayList Class and Override all the methods that add elements to the ArrayList and check if the element is instanceof the parent Class and not an instanceof the child Class in your implementation and call the Super method for process of adding the element(s).
No. You just can't stop it. We can use every Child as a Parent. Every Child extends Parent and apparently it's a Parent as well.
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).