How to Call a Subclass Method From a SuperClass Object - java

lets suppose i have this Parent Class
public abstract class Parent
{
private String name;
private String surname;
public Parent(String name, String surname)
{
this.name=name;
this.surname=surname;
}
and lets suppose i have many child classes like that and everyone of them has it's own different attributes to add to their parent ones
public class Child extends Parent
{
private String favColor;
public Child(String name,String surname,String favColor)
{
super(name,surname);
this.favColor=favColor;
}
public getFavColor()
{
return this.favColor
}
now i'm in this situation
Parent parent = new Child(name,surname,favColor);
and what i want to do is calling the method getFavColor() on the object parent like this
parent.getFavColor();
is this working? i guess not, so how could i be able to call such method on such object? i thought of declaring abstract getters of childs attributes on the superclass but that doesn't sound very prone to the open/closed principle, because in a time in future when i will want to add more child-like classes i will have to declare every getters of the child attributes in the superclass which is not supposed to know about his childrens.
thank you very much :)

In this case you can't call the getFavColor() method. The method is defined only in Child class and your reference is Parent. For this, is necessary the definition the getFavColor() method in Parent Class.
You would create a abstract method fav() in Parent class:
public abstract class Parent
{
private String name;
private String surname;
public Parent(String name, String surname)
{
this.name=name;
this.surname=surname;
}
public abstract String fav();
}
So called:
parent.fav();
Thus, you can implement the method in different ways on your children, such as:
public class Child extends Parent
{
private String favColor;
public Child(String name,String surname,String favColor)
{
super(name,surname);
this.favColor=favColor;
}
public String fav()
{
return this.favColor;
}
}
And:
public class SecondChild extends Parent
{
private String favSport;
public Child(String name,String surname,String favColor)
{
super(name,surname);
this.favColor=favColor;
}
public String fav()
{
return this.favSport;
}
}
Use this only if the signature of methods are equals in all children (in your case, if all children methods return a String).

You would need an abstract method to do that. Your parent is already abstract so that's good. It would go something like this:
public abstract class Parent {
private String name;
private String surname;
public Parent(String name, String surname) {
this.name = name;
this.surname = surname;
}
public void showFavColor() {
system.print.ln(this.getFavColor());
}
abstract string getFavColor();
}
public class Child extends Parent {
private String favColor;
public Child(String name, String surname, String favColor) {
super(name, surname);
this.favColor = favColor;
}
#Override
public String getFavColor() {
return this.favColor
}
}
Every child of the parent MUST extends the abstract function. Since the function is technically declared in the parent, it is accessible from it.
This means, you could do
Parent parent = new Child(name,surname,favColor);
parent.showFavColor();

Related

Is it advisable to create an empty POJO class in Java?

Suppose I have a superclass A and it has fields
class A {
String name;
int age;
setName(String name);
getName();
setAge(int age);
getAge()
}
I have multiple classes that extend A and add more fields along with the getters and setters.
Now there is another class, say B, which requires name and age, which is already provided by class A.
So should I go ahead and create class B without any field and simply it extends class A, or should I directly use class A?
class B extends A {}
P.S - I am using generics, which gives me a warning when I directly use superclass A, but the functionality is working fine. Please suggest.
Mostly the design wont be proper and justified if u just create a Class that do not have its own state, but yes it make sense if
A is abstract class i.e. you want to restrict the users to create an instance of A hence mark it abstract , then by creating B you are creating an implementation of A.
below is the example for the same
abstract class A{
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class B extends A{}
also to make code more dynamic at runtime if u want to just use the parent class fields into ur function then probably u can do this
abstract class A{ // you can altogether remove 'abstract' and not create a B class
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class B extends A{}
class C extends A{
protected String location;
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
now see the below method
public static <T extends A> void printName(List<T> list) {
for (T t : list) {
System.out.println(t.getName());
}
}
this qualifies for List<B>, List<C>
There is really no reason, that I can think of, where you need to extend a class without changing anything. Maybe you feel that you will need it in the future. This violates the YAGNI principal.
Just use Class A. You can make changes when they are needed.
It really is pointless. If it gives you a warning, there is probably a good reason for it. Unless you have a niche use case and know what you are doing, the empty class serves no purpose other than adding useless files to your project

Why does a superclass reference calling an overridden method appear polymorphic, but not if it takes an overridden member variable?

package main.java;
public class Demo {
public static void main(String[] args) {
BClass bClass=new BClass("han","男");
AClass aClass=bClass;
System.out.println(aClass.getSex());
System.out.println(aClass.sex);
}
}
The execution result of this class is
男
null
The results are confusing to me. When the superclass calls the overridden method, the results meet my expectations, but when it calls the overridden variable, the results confuse me.so why does a superclass reference calling an overridden method appear polymorphic, but not if it takes an overridden member variable?Here's the entire code.
package main.java;
public class Demo {
public static void main(String[] args) {
BClass bClass=new BClass("han","男");
AClass aClass=bClass;
System.out.println(aClass.getSex());
System.out.println(aClass.sex);
}
}
package main.java;
public class AClass {
private String name;
public String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package main.java;
public class BClass extends AClass{
private String sex;
public BClass(String name,String sex) {
this.sex = sex;
super.setName(name);
}
#Override
public String getSex() {
return sex;
}
#Override
public void setSex(String sex) {
this.sex = sex;
}
}
While you can override a method, you can't override a field in a subclass; you are actually just declaring a field with the same name. To allow the field to also be visible in the child class, you can change its visibility to protected or package private (default modifier), if both classes are in the same package. Demo.
public class BClass extends AClass{
public BClass(String name,String sex) {
this.sex = sex;
super.setName(name);
}
#Override
public String getSex() {
return sex;
}
#Override
public void setSex(String sex) {
this.sex = sex;
}
}
public class AClass {
protected String name, sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
Java doesn't allow you to really override a field.
Your BClass actually has two fields named sex, one from AClass, and one from BClass. And Java syntax doesn't really help you finding out which one is meant when you write something like x.sex. It's as if you had defined two different fields, sex_a in AClass and sex_b in BClass, only with the complication that references to both are written like x.sex, without a clear hint which of the two is meant here.
In your case:
Your BClass instance will have its sex_b initialized, and the sex_a empty (null).
aClass.getSex() always calls the most specific method, based on the instance's runtime class, being BClass. So it chooses the method from BClass, returning sex_b, and thus prints the sex.
aClass.sex accesses one of the two sex fields, depending on the variable's compile-time-deducible type, in your case being AClass. So it prints the sex_a value, being null.
Seasoned Java developers typically do their best to avoid this situation, as it can be very confusing.
If the two fields conceptually have the same meaning, do it as you did with the name field, having only one field in the parent class, and have the subclass access it via getters and setters (or by declaring protected visibility for the field).
If the two fields have conceptually different meanings (can an object have two different sexes?), use different names.
As per the Java specifications, the instance variables are not overridden from a super class by a sub class when it is extended.

Java - Inheritance issue with two children sharing a parent method [duplicate]

I have a abstract Parent class that has multiple children. I'd like the child to be able to have a variable that is the same for every instance of that child. I'd prefer not to pass a constructor to the child to tell it it's name because that just seems silly when it can be hardcoded. From what I've read doing the following "hides" the parents instance variable and doesn't work as I want.
public abstract class Parent {
public String name = "the parent";
public getName(name);
}
public class Child1 extends Parent {
public String name = "Jon";
}
public class Child2 extends Parent {
public String name = "Mary";
}
Child1 c = new Child1();
c.getName(); // want this to return "Jon", but instead returns "the parent".
To be clear, basically what I want is something like c.getClass().getName() but I don't want to have the result of that dependent on the Class name, but rather on a hardcoded value.
Thanks
You could declare an abstract method in the parent and have each child implement the method to return the appropriate name, like this:
public abstract class Parent {
public abstract String getName();
}
public class Child1 extends Parent {
private static final String NAME = "Jon";
public String getName() { return NAME; }
}
public class Child2 extends Parent {
private static final String NAME = "Mary";
public String getName() { return NAME; }
}
Depending on what you're actually trying for, there are a couple of solutions. One is to make the child classes provide the name to the parent:
public abstract class Parent {
protected Parent(String name) {
this.name = name;
}
public getName() {return name;}
}
public class Child1 extends Parent {
public Child1() {
super("Jon");
}
}
public class Child2 extends Parent {
public Child2() {
super("Mary");
}
}
Another is to use method inheritance like Isaac Truett suggests.
Create a static final String in each child that has your hard-coded name:
public class Child1 extends Parent
{
public static final String NAME = "Jon";
}
Use a method instead of a field (variable):
public abstract class Parent {
public String getName() {
return "the parent";
}
}
public class Child1 extends Parent {
public String getName() {
return "Jon";
}
}
public class Child2 extends Parent {
public String getName() {
return "Mary";
}
}
In Java, at least, you can only override methods, not variables.
Another option would be to have Parent's constructor take the name as a parameter. If you do this it's best if Parent is abstract and all of the constructors take the name parameter. Then subclasses are required to pass in the name, which would typically be done something like this:
public class Child1 extends Parent {
public Child1() {
this("Jon");
// ...
}
}
Actually, even with the method overriding approach, it's nice if Parent is abstract so you can make getName() abstract.
The reason why your call to getName() doesn't return the child's name is because you've created a new variable call name within the child. Try this:
public class Child3 extends Parent{
public String name = "Jon";
public String getNames(){
return super.name + " : " + name;
}
}
You will see:
the parent : Jon
The correct way to set the name of the child into the parent's name variable is to say:
super.name = "Jon";
You need to overwrite the getName function in order to get the result you want.
Because the new String name is not replacing the parent name so the getName function is actually reading the parent String
Why not use the constructors?
public abstract class Parent {
public String name = "the parent";
public String getName() {
return name;
}
public void setName(String s){
name = s;
}
}
public class Child1 extends Parent {
public Child1() {
setName("Jon");
}
}
public class Child2 extends Parent {
public Child2() {
setName("Mary");
}
}
Child1 c = new Child1();
c.getName();
// Prints 'Jon'
You could do this using Java Reflection... but it's not a very clean way of doing things:
public abstract class Parent {
public String name = "the parent";
public String getName() throws Exception { return getClass().getField("name").get(this).toString(); }
}
Although I think Isaac's approach is the best way to approach the solution.

Passing object as parameter for constructor

I have 3 classes. These classes are Class1, Parent and Child. I'm having some trouble to figure out how to write a constructor I need for my Child class.
public Class1
{
private String firstName;
private String lastName;
public Class1()
{
firstName="";
lastName="";
}
public Class1(String firstName, String lastName)
{
this.firstName=firstName;
this.lastName=lastName;
}
//Methods and stuff
}
public Parent
{
private Class1 class1;
private double number;
public Parent();
{
class1=new Class1();
number=0;
}
public Parent(Class1 c, double n)
{
Class1=c;
number=n;
}
//Methods and stuff
}
public Child extends Parent
{
private String string;
private Boolean boolean;
public Child(Class1 class1, double n, String s, Boolean b)
{
//Don't know how to get the Class1 part to work
//Don't know how to get the double to work
string=s;
boolean=b;
//Methods and stuff
}
I don't know how to write the code so that I can get my constructor to take the arguments like this:
new Child(new Class1("String", "String"), 10, "String", true);
I hope this helps clarify what my problem is.
Create Child constructor as
public Child(Class1 objClass1, double number, string str, boolean bool){
super(objClass1,number);
this.str=str;
this.bool=bool;
}
Create Parent constructor as
public Parent(Class1 objClass1, double number){
this.objClass1=objClass1;
this.number=number;
}
and you can called the child constructor as
Child objChild=new Child(new Class1(str1,str2),number,str,bool);
I'm not going to give you the code, because you've not given us enough information, but let's assume you've got a class structure like..
public class Parent
{
private String field;
public Parent(String field) {
this.field = field;
}
}
public class Child extends Parent {
private String field;
public Child(String field)
{
this.field = field;
}
}
What you can do is specify a constructor in your Child class that passes the variables up the inheritance chain, to your Parent class:
public Child(String field, String parentField)
{
super(parentField); // Calls the parent class.
this(field);
}
So what you've done there, is passed the parentField up to the Parent class, and you've called your existing constructor that accepts a single String parameter.
Apply this principle to your code and you'll get it in minutes.

Inheriting #JsonCreator annotations from Superclass

I have a number of objects with a set of shared properties in a superclass:
public Superclass {
int id;
String name;
...
}
And I have subclasses which inherit from the superclass but each of them need their own fully-described #JsonCreator
public Subclass1 extends Superclass {
String color;
#JsonCreator
public Subclass1(#JsonProperty("id") int id,
#JsonProperty("name") String name,
#JsonProperty("color") String color)
{
super(id, name);
this.color = color;
}
}
public Subclass2 extends Superclass {
int height;
#JsonCreator
public Subclass1(#JsonProperty("id") int id,
#JsonProperty("name") String name,
#JsonProperty("height") int height)
{
super(id, name);
this.height = height;
}
}
Is there any way for Jackson (2.x) to pull information from the superclass regarding expected JSON fields and to avoid this repetition?
Since your classes do not appear to be immutable you could put #JsonSetter annotations on setter methods in the base class for the "id" and "name" properties. Then deserialization will create the appropriate subtype and use the setters instead of a constructor.
public class Superclass {
private int id;
private String name;
#JsonSetter
public void setId(int id) { ... }
#JsonSetter
public void setName(String name) { ... }
}
public Subclass1 extends Superclass {
private String color;
#JsonSetter
public void setColor(String color) { ... }
}
public Subclass2 extends Superclass {
private int height;
#JsonSetter
public void setHeight(int height) { ... }
}
You might be able to use #JsonSubTypes as well. This annotation would go on Superclass and you would have to list references to each subtype (Subclass1 and Subclass2). I don't know off the top of my head if this would allow you to leverage a #JsonCreator in Superclass to avoid repeating the "id" and "name" properties in the subclasses but I figure it's worth a try. The down side of this approach is that your base class has explicit references to subtypes.

Categories