I want to instantiate a child class in Java from within a parent class. However, when I do this, and attempt to call a parent's method from the constructor of the child (with super), the returned field is null. If I changed this to instantiating the parent from the main() method, the field returns how it is expected (a String). I'm not sure whats happening here, can anyone explain?
Main class:
public class MainFunc {
public static void main(String[] args) {
javaClass jv = new javaClass("Bobby");
jv.makeJ2();
}
}
Parent Class:
public class javaClass {
String name;
public javaClass(){
}
public javaClass(String s) {
setName(s);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void makeJ2 (){
javaClass2 jv2 = new javaClass2();
}
}
Child Class:
public class javaClass2 extends javaClass {
String name;
public javaClass2() {
super();
String superTitle = super.getName();
System.out.println("HEY " + superTitle);
}
}
This returns:
HEY null
Instead of:
HEY Bobby
You cannot access child class from parent class,child class has inherited the parent class, not the other way. But you can make your String static for it to work the way you want.
public class javaClass {
static String name;
Design wise, a parent should never instantiate a child class. It is not like human reproduction system. In OOPS world, child classes need to declare their own parents, and only these child classes know about their parents and not vice-versa.
Even though intention in the posted question is to make use of Inheritance, it is not happening by the virtue of the convoluted code. This is how the code is running:
Test creates a javaClass object named jv. At this point jv has an attribute name, value of which is set to Bobby
jv's makeJ2 method is called, this creates a very new object of the class javaClass2, named jv2. The parent class of this very new object does NOT have any field set, and nothing has been passed to the parent class's constructor. Hence there is NO relation between the parent of this new object jv2 and the previously created jv object and that is why:
String superTitle = super.getName(); returns null as expected
The exact problem is that the child object is not passing along any information for the parent's attributes to be set. That can happen through overloaded supers or by setting super properties but not just by calling super(). See a good explanation of how inheritance works in java.
Please do not use static just to make it work
Lastly, I suggest reading about composition too, as that is slightly more preferable over inheritance, for some good reasons.
In your child class you did not overload the constructor for name field. From the overloaded constructor you should invoke super(name);
The output that is generated is because of two reasons.
Because you have called super() in the javaClass2 constructor and not super(String str)
And because the parent java class that the child class is instantiating is not the same as the one you are calling the method makeJ2(jv.makeJ2()) from.
Also the blow link can help you understand the instance variable overriding in java.
Java inheritance overriding instance variable [duplicate]
Base on your progress:
You initiate the parent class:
javaClass jv = new javaClass("Bobby");
javaClass name attribute will be "Bobby"
Now the time you call:
jv.makeJ2();
It will initiate the new javaClass2:
javaClass2 jv2 = new javaClass2();
It call the super(); mean: javaClass() in javaClass not javaClass(String s)
So now your new child javaClass2 is extended from new javaClass wiht its name is new (null).
If you want javaClass2 print "Buddy", you should:
public javaClass2(String s) {
super(s);
String superTitle = super.getName();
System.out.println("HEY " + superTitle);
}
jv and jv2 are totally two different objects in the memory.
After all that is the fundamental meaning of "new" operator in Java.
you have used "new" operator twice in your code.
So it means you have two completely different objects.
jv's name is set as "Bobby" but nobody has set a name for the second object jv2 !
Imagine this:
class Manager extends Employee
{
....
public void setPMPCertified(boolean b)
{
...
}
}
//Generally Software engineers
class Employee
{
....
public void setName(String n)
{
.....
}
}
Manager m1 = new Manager();
Employee e1 = new Employee();
m1.setName("Robert");
m1.setPMPCertified(true);
e1.setName("Raja");
Robert is a manager. Raja is a software engineer.
They are completely two different data (object) in the memory.
Just because manager extends employee Robert and Raja cannot become single object.
Look at the fact we have used the new operator twice to create two objects.
Please note manager does NOT have the setName method.
It comes from the parent (Employee).
setPMPCertified is only applicable to managers.
we don't care if a software engineer is PMP certified or not!! :)
Related
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......
}
}
}
This question already has answers here:
Implementing two interfaces with two default methods of the same signature in Java 8
(7 answers)
Closed 2 years ago.
Java 8's default methods in an interface can be called from the child class using InterfaceName.super.methodName . Why doesn't Java 8 allow us to use a similar syntax to call the specific class's method name? Can this resolve the Diamond Problem encountered for multiple inheritance?
class Employee {
public static void displayName() {
System.out.println("Employee!");
}
}
class Engineer extends Employee {
public static void displayName() {
System.out.println("Engineer!");
}
}
class Manager extends Employee {
public static void displayName() {
System.out.println("Manager!");
}
}
public class Resource extends Engineer,Manager {
public static void main(String args[]) {
//Insert similar code here like InterfaceName.super.methodName to call any of the above methods to handle multiple inheritance.
}
}
In Java 8, you can not extend (inherit) multiple classes all in one shot. What I mean by this is that if you write:
public class Resource extends Engineer, Manager { //This generates a compiler error.
}
However, you may inherit multiple classes into one, main class by making a chain of inheritance.
public class Master {
public void method1(){};
}
public class Child1 extends Master{
public void method2() {};
}
public class Child2 extends Child1 {
//you can access method 1 and method 2 here by simply calling
method1();
method2();
}
A way you can go about addressing your issue is to write an "EmployeeInterface" and write an "EmployeeClass". To access the methods in "EmployeeClass", you must make an object of the "EmployeeClass" in your main method. You will need to write a constructor to pass the name of the employee in. I will provide an example here:
public interface EmployeeInterface {
public void displayName();
public void setName(String name);
}
The above is an Interface. An interface contains the methods that you want to use in a class, however, you do not yet define them here. You only write the method headers. Think of this as a shopping list. Writing an item such as bread on a shopping list does not mean you will now have bread, it just marks it as an item that needs to be purchased.
Next, you will need to write a class implementing the EmployeeInterface.
public class EmployeeClass implements EmployeeInterface{
private String employeeName;
public EmployeeClass(String name) { //This is a constructor
this.employeeName = name;
}
#Override
/**
* This function will display the name of the employee.
*/
public void displayName() {
System.out.println(employeeName);
}
#Override
/**
* This function with use the given string and change the employee's name.
*/
public void setName(String name) {
this.employeeName = name;
}//end of setName method
}//end of class
Above is the class that implements the EmployeeInterface. It looks at the Interface and says that you must define what these methods do. This is like looking at your shopping list and seeing bread, and going to the store and buying it.
There is also a constructor in this class. A constructor in java is a method that is executed upon the instantiation of an instance of a class. This means that whatever code you write in the constructor, it will be run once and only once when you make an object of the class. Constructors must be spelled the same as the class, is case sensitive, and must be public. You can add as many parameters as you'd like.
We use #Override over the functions in the class because we are overriding (Changing the body) from nothing to our definition from the EmployeeInterface. Depending on your IDE/Compiler, it may work without the #Override tag, but it is highly reccomended that you do this.
In the constructor, you see we use this.employeeName = name; the "this" keyword refers to the field (variable) within the class that we write it in. In this case, it is not necessary, because the name of the variable in the class and the name of the variable being passed in are different. But in the case that variable names are the same, you can use "this.variableName" to specify the class variable.
Finally, to use these classes, you must make a main method in a separate class to execute these functions. Making the main method is like making a sandwich out of the bread that you purchased at the store.
public class Main {
public static void main(String[] args) {
EmployeeInterface manager = new EmployeeClass("Bob");
EmployeeInterface engineer = new EmployeeClass("Mary");
System.out.println("The name of the manager is: ");
manager.displayName();
System.out.println("The name of the engineer is: ");
engineer.displayName();
manager.setName("Jack");
System.out.println("The new manager's name is: ");
manager.displayName();
}//end of method Main
}//end of class Main
Above is the method that executes the methods that you defined in the EmployeeClass using the EmployeeInterface. First, you create an object of the class, of the type that is the name of the Interface.
EmployeeInterface manager = new EmployeeClass("Bob");
This is an object of the EmployeeClass, and we called it manager. We made it of type EmployeeInterface because we want to be able to use the methods we defined in the EmployeeInterface. We write "= new EmployeeClass("Bob");" afterward because we want to make a new Instance of the EmployeeClass, and pass the String "Bob" into our constructor.
Next, we display the name of the manager.
System.out.println("The name of the manager is: ");
manager.displayName();
This will display the name of the manager.
We can also change the name of the manager with our defined "setName()" function.
manager.setName("Jack");
We call the function like this and pass in the String "Jack" which will become the new name for the manager.
Upon execution of the Main method, we get this output:
Image of the output
All in all, this solution does not use inheritance of methods to print the names of different employees, but uses an EmployeeInterface, along with a definition of the Interface, EmployeeClass, to store and display the employee names. Rather than making a new class for every employee, you make a new object with the parameters containing the name of the new employee in the main method.
I hope this answered your question, and please do reply if you require any more clarifications.
Here I also include some articles about the Java concepts I talked about.
Here is a resource for Inheritance and Interfaces.
Interfaces on Oracle
Inheritance on Oracle
Constructors on Oracle
I couldn't grasp the idea why the codes below prints console Person twice. I thought it should have been Person and Student. When getInfo() inside printPerson() is called through "a" object, why is the one inside Person class being invoked and why is the one in the Student class not invoked? Thanks in advance.
class deneme{
public static void main(String[] args) {
Person b = new Person();
b.printPerson();
Student a = new Student();
a.printPerson();
}
}
class Student extends Person {
public String getInfo() {
return "Student";
}
}
class Person{
private String getInfo() {
return "Person";
}
public void printPerson() {
System.out.println(getInfo());
}
}
You have attempted to override a private method. That is not possible. See Override "private" method in java for details. Because Student is not able to see Person.getInfo Java assumes you are declaring a new method.
If you make getInfo public you will find that Student is printed instead.
This is a good argument for using the #Override annotation before any methods that you are intending to override a superclass's method. It isn't just documentation - it can avoid subtle errors by letting your IDE warn.
I think that is because Person.getInfo() is private and you cannot override private methods, so a.printPerson() will actually call its own getInfo(). Always annotate methods you want to override with #Override; the compiler will throw an error if there was no method found in the parent class to override.
If you want to make Person.getInfo() private to other classes but still want to override it, simply make it protected.
So as far as I understand the Substitution principle doesn't allow a subclass to have fields which have a weaker access privilege because otherwise it could potentially violate information hiding and also because a subclass should always offer at least the same behavior of its parent one. That makes sense to me.
but at the same time I don't understand how it could make sense to extend a field or method access level? I have a private field in the parent class while public in the child class. Could you give me an example of why this makes sense? Or is it just because of a design choice?
it is not true as you mentioned for private field. you can't extend a private field from super class to subclass. if you declare a field with that same name, you define a new field for that subclass.
However, you can change package access and protected access to something more like public and this doesn't make any problem because super class doesn't provide that for it's subclass but subclass maybe change its behavior depend on its state and wants to provide that for other users.
For example when it protected you can only access that in that package and in subclass. however maybe you do some works in it that doesn't good for public implementation. (if you make something public, you must support it for future release) however in subclass you might want to override it and add some new feature to it and provide a result that is usable by other people.
A good example (always java provide best example):
If you see, java declared this in Object class:
class Object {
protected native Object clone() throws CloneNotSupportedException;
}
so no one can call clone() on it. it is good because maybe I don't want to provide clone() for my class. however if I want it, it is easy to override that and make it public for other people and also call super.clone() in it for use feature which is implemented before for create a new copy of my class. Isn't great?!
https://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html
The parent and child have 2 separate instances of test. As you can see in this example.
public class Main {
public class Parent{
private String test = "parent test";
String getTest() {
return test;
}
}
public class Child extends Parent {
public String test = "child test"; // defining it here hides the parent field
#Override
String getTest() {
return test;
}
}
public static void main(String[] args) {
Main main = new Main();
Parent parent = main.new Parent();
System.out.println(parent.getTest());
Child child = main.new Child();
System.out.println(child.getTest());
}
}
Output:
parent test
child test
it could potentially violate information hiding
Information hiding, while a good practice, has little to do with the Liskov substitution principle.
(A) subclass should always offer at least the same behavior of its parent (class).
This is true, but is achieved by disallowing a stricter access modifier on an inherited member. A weaker access modifier surfaces additional behavior.
class A {
private int lastInput;
protected int getLastInput() {
return lastInput;
}
public int getSquareValue(int input) {
lastInput = input;
return getLastInput()*getLastInput();
}
}
class B extends A {
public int getLastInput() {
return super.getLastInput();
}
}
A aa = new A();
B bb = new B();
A ab = bb;
// All behaviors of A exist in B as well.
// B can be substituted for A.
System.out.println(aa.getSquareValue(5)); // 25
System.out.println(ab.getSquareValue(5)); // 25
// B also has new behaviors that A did not surface.
// This does not prevent B from substituting for A.
System.out.println(bb.getLastInput()); // 5
This question already has answers here:
Do subclasses inherit private fields?
(21 answers)
Closed 7 years ago.
I have 2 classes in JAVA:
Parent Class:
public class Parent {
private int age;
public void setAge(int age) {
this.age = age;
}
public int getAge(){
return this.age;
}
}
Child Class:
public class Child extends Parent{
public static void main(String[] args){
Parent p = new Parent();
p.setAge(35);
System.out.println("Parent "+p.getAge());
Child c = new Child();
System.out.println("Child " + c.getAge());
}
}
Output is:
Parent 35
Child 0
The private members are not inherited in JAVA
When calling getAge() method on child class instance, why does it run successfully and even gives output as 0?
private member is not inherited, but public methods accessing it yes.
When you create an object of type Child all variables of the superclass are created also if not directly usables.
If there are public methods in the superclass you can access them from the subclass. And if those methods access the private variable values of the superclass you can indirectly via public methods access them.
Access modifiers as the name suggest can only affect the accessibility of variables/methods not inheritance, you cannot access age variable directly in your Child class as it is private but it doesn't mean that it is not present for child object.
So in your case the two public methods are accessible from both classes but inside your Child class you cannot use age directly unless you change its access modifier to protected or public
For more better understanding have a look Controlling Access to Members of a Class
Also you can check Do access modifiers prevent inheritance?
Inheritance : You are getting value from method, not from variable.
Default Value :
Class Type (Non-primitive, Object) : null
Primitive Type (int, float, etc) : 0
Please refer Java docs about inheritance : https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
For the Parent class there is no constractor , therefore JAVA makes a defualt constractor.
When Child extends Parent he actually first go the his parent constactor.
You can build in Parent class this constructor:
public Parent(){
this.age = 15;
}
and you will see that the child age will be 15 when you print it.
You are accessing getAge() method which is public and is legal. The implementation of getAge() is accessing it's private members, not you.
One of the most fundamental aspects of a programming language is how it initializes data. For Java, this is defined explicitly in the language specification. For fields and array components, when items are created, they are automatically set to the following default values by the system:
numbers: 0 or 0.0
booleans: false
object references: null
This means that explicitly setting fields to 0, false, or null (as the case may be) is unnecessary and redundant. Since this language feature was included in order to, in part, reduce repetitive coding, it's a good idea to take full advantage of it. Insisting that fields should be explicitly initialized to 0, false, or null is an idiom which is likely inappropriate to the Java programming language.
Furthermore, setting a field explicitly to 0, false, or null may even cause the same operation to be performed twice (depending on your compiler).
public class Child extends Parent{
public static void main(String[] args){
Parent p = new Parent();
p.setAge(35);
System.out.println("Parent "+p.getAge());
Child c = new Child();
System.out.println("Child " + c.age); //can't access private
System.out.println("Child " + c.name); //can access public variable
System.out.println("Child " + c.getAge()); //can access public method
System.out.println("Child " + c.getName());//can,t access private method
}
}
class Parent {
private int age;
public String name;
public void setAge(int age){
this.age = age;
}
private String getName(){
return name;
}
public int getAge(){
return this.age;
}
}
Private variable can't be access outside the class. But we can make it accessible through getter and setter. Here OOP concept of Encapsulation comes in.
public methods, variables defined in the Parent class can be accessible in the child class. Here OOP concept of Inheritance comes in.
Adding a few cents of mine. Child class cannot access the private variable age which part of Parent class. But age state is still part of the Child object. You can access using get and the set method. To illustrate it further, you can invoke setAge() on the child object to set proper age of child.
public class Child extends Parent {
public static void main(String[] args) {
Parent p = new Parent();
p.setAge(35);
System.out.println("Parent "+p.getAge());
Child c = new Child();
c.setAge(20);
System.out.println("Child " + c.getAge());
}
}
Output:
Parent 35
Child 20
Private member not inherited right , but we can access it by the public method . So in your case private member is access by public method .
And the reason of value is zero , because the value of variable age by parent class object not child class object . so when you access value of age variable by child class object , it print the default value of variable age .