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

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.

Related

Java factory but objects have slightly differrent attributes

I want to program a factory that creates two types of People which are "Employee" and "Entrepreneur". They both share the same basic "Person" attributes but they also implements their unique ones.
The problem is that if i want to return a method or an attribute that is not declared in the "Person" abstract class the program doesn't find it (since obviously I'm generating an object that is type "Person" and not specifically "Employee" or "Entrepreneur" ).
How do i tackle this problem?
This is the Demo class
public class Demo{
public static void main(String[] args){
PersonFactory pf = new PersonFactory();
Person p1 = pf.getPerson("Employee");
p1.presentation();
System.out.println(p1.getComplanyName());
}
}
This is the abstract class
public abstract class Person{
String name;
String surname;
abstract void presentation();
}
Those are the two concrete classes that extend Person
public class Entre extends Person{
int licenseNumber;
#Override
public void presentation(){
System.out.println("hi i'm an Entrepreneur");
}
public int licenseNumber(){
return licenseNumber;
}
}
public class Empl extends Person{
String companyName;
#Override
public void presentation(){
System.out.println("hi i'm an employee");
}
public String getCompanyName(){
return companyName;
}
}
Finally the Factory
public class PersonFactory{
public Person getPerson(String type){
if(type.equalsIgnoreCase("ENTREPRENEUR")){
return new Entre();
}
else if(type.equalsIgnoreCase("Employee")){
return new Empl();
}
return null;
}
}

Java: Calling a parent's method with child's member variable

Let's say I have an abstract parent class that has member variables which are used in a method.
public abstract class Person{
public String jobTitle;
public void printJob(){
System.out.println(jobTitle);
}
}
If I now have two child classes
public class Teacher extends Person{
public String jobTitle = "Teacher";
}
public class Janitor extends Person{
public String jobTitle = "Janitor";
}
and I want to avoid code cloning, i.e. implementing the same printJob()-method in both classes, I now have a problem, since the printJob()-method is unable to access member variables of the child classes.
Is there any way that i can call a parent classes' method but have the method use the child classes' member variables?
You can use abstract methods like this
public abstract class Person {
public void printJob() {
System.out.println(getJobTitle());
}
protected abstract String getJobTitle();
public static void main(String[] args) {
Person teacher = new Teacher();
Person janitor = new Janitor();
System.out.println(teacher.getJobTitle());
System.out.println(janitor.getJobTitle());
}
}
class Teacher extends Person {
#Override
protected String getJobTitle() {
return "Teacher";
}
}
class Janitor extends Person {
#Override
protected String getJobTitle() {
return "Janitor";
}
}
Updated after op's comment for code cloning...
public class Person {
public static void main(String[] args) {
System.out.println(new Teacher().job);
System.out.println(new Janitor().job);
}
private static class Teacher extends Person {
private String job = "Teacher";
}
private static class Janitor extends Person {
private String job = "Janitor";
}
}

How to Call a Subclass Method From a SuperClass Object

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();

I need help creating constructors and returning boolean and strings

I need help fixing my code with the basic concepts listed above. To save from clutter, I took a screen shot of the directions here: https://imgur.com/SdiotUi
However, when I run my code it isn't working. I know there are a lot of errors but I'm having trouble fixing them even though I've spent the past few hours googling the correct way to do this.
When I create the first constructors I am not sure if I am assigning the name and legs correctly, I am having trouble returning "true", I get an error calling the parent class taking one argument, and I don't think I am overriding the abstract class correctly.
My code:
public class Animal1 {
private String animalName;
public int numberOfLegs;
public Animal1(String name){
name = animalName;
name = "John";
}
public Animal1(String name, int legs){
name = animalName;
legs = numberOfLegs;
name = "Jack";
legs = 4;
}
public String getName(){
return animalName;
}
public int getLegs(){
return numberOfLegs;
}
public void isAMammal(){
return true;
}
public void isCarnivorous(){
return true;
}
public abstract class getHello{
}
}
public class Cat1 extends Animal1{
public Cat1(String name){
Animal1.name;
}
public abstract class getHello{
return "Meow";
}
}
public class Dog1 extends Animal1{
public Dog1(String name){
Animal1.name;
}
public abstract class getHello{
return "Woof";
}
}
public abstract class Animal1 { // If you want to have an abstract method, declare the class as abstract
private final String animalName;
private final int numberOfLegs; // better of using private and make it final since it's not going to change.
public Animal1(final String name, final int legs){ //better making the input parameters final since they are not supposed to be changed
//name = animalName;
//legs = numberOfLegs;//it assigned the field to an input parameter. that will take no effect on the object created.
animalName = name;
numberOfLegs = legs;
}
public String getName(){
return animalName;
}
public int getLegs(){
return numberOfLegs;
}
public boolean isAnimal(){ //boolean function needs a return type too!!
return true;
}
public boolean isCarnivorous(){
return true;
}
public abstract String getHello(); // an abstract method has same requirement as a normal method besides the abstract modifier. it will need a return type. And it ends with a semicolon
}
public class Cat1 extends Animal1{
public Cat1(final String name){
super(name, 4); //use super to call parent constructor
}
#Override
public String getHello(){
return "Meow";
}
}
public class Dog1 extends Animal1{
public Dog1(final String name){
super(name, 4);
}
#Override
public String getHello(){
return "Woof";
}
}
First, it looks like a few of your methods are declared as classes. I assume you wanted to make them abstract methods. They need to be changed to:
public abstract String getHello();
Note that abstract methods can only be declared in an abstract class. So, you need to redefine Animal1 as abstract.
public abstract class Animal1
Next, when you implement the abstract method, you define it as
public String getHello()
If you are using an IDE like Eclipse it will automatically offer to generate this method.
Finally, when using your constructor in your child classes like Cat1, you are trying to set "name" as if it was a static variable and bypassing the constructor you already had set for Animal1. The best way to correct this is to change the constructor in Cat1 and Dog1 to call the super constructor.
public Cat1(String name){
super(name);
}

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.

Categories