How private variables in superclass is inherited in the subclass here? [duplicate] - java

This question already has answers here:
Private members in Java inheritance
(5 answers)
Closed 4 years ago.
package practice;
class person{
private String firstname;
private String lastname;
public person(String firstname,String lastname){
set_first(firstname);
set_last(lastname);
}
public String get_first() {
return firstname;
}
public void set_first(String firstname) {
this.firstname=firstname;
}
public void set_last(String lastname) {
this.lastname=lastname;
}
public String get_last() {
return lastname;
}
}
class employee extends person{
private int empid;
public employee(String firstname,String lastname,int empid){
super(firstname,lastname);
set_empid(empid);
}
public void set_empid(int empid) {
this.empid=empid;
}
public int get_empid() {
return empid;
}
}
class testing_super_keyword {
public static void main(String args[]) {
employee emp=new employee("John","Jackson",1234);
System.out.println(emp.get_first()+" "+emp.get_last());
System.out.println(emp.get_empid());
}
}
Can anybody explain how the class employee inheriting the class person even when the attributes of the class person "firstname" and "lastname"have been declared as private?
AS of my knowledge a superclass variable declared as private cant be inherited by the sub class.

This is a considered a good programming practice where you do not give direct access to the instance variables of a class by using private access specifiers and instead provide the public getter and setter methods to get and set the instance variables.
In you case you cannot access the instance variables of SuperClass directly but you have the public getter and setter methods(get_first, set_first) declared and you can make use of them.
Also, as per the Java naming convention use the camelCase names for functions. For example instead of get_name use getName and son on.

Related

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.

Unable to access methods using dynamic polymorphism [JAVA] [duplicate]

This question already has answers here:
Upcasting/Downcasting in Java
(3 answers)
Closed 3 years ago.
I am trying to solve the following problem
I have made the following hierarchy.
public abstract class Employee{
private String name;
private Integer id;
protected Type type;
Employee(){}
Employee(String name,Integer id){
this.name = name;
this.type = type;
}
abstract public void calculatePay();
protected void benifits(){
System.out.println("Basic Benifts");
}
public void printType(){
System.out.println(this.type);
}
}
public class Intern extends Employee{
Intern(){
super("default",123);
}
Intern(String name,Integer id){
super(name,id);
this.type = Type.Intern;
}
public void calculatePay(){
System.out.println("Intern Pay");
}
}
class Developer extends Employee{
Developer(){
super("default",123);
}
Developer(String name,Integer id){
super(name,id);
this.type = Type.Developer;
}
public void calculatePay(){
System.out.println("Developer Pay");
}
protected void benifits(){
super.benifits();
System.out.println("Developer Benifits");
}
}
class Manager extends Developer{
public Manager(){
super("default",123);
}
public Manager(String name,Integer id){
super(name,id);
this.type = Type.Manager;
}
public void calculatePay(){
System.out.println("Manager Pay");
}
public void benifits(){
super.benifits();
System.out.println("Manger Benifits");
}
public void foo(){
System.out.println("foo");
}
}
And the driver is as follows
class Driver{
public static void main(String args[]){
Employee manager = new Manager("Ali",1);
manager.calculatePay();
manager.benifits();
manager.printType();
manager.foo();
}
}
Type is an Enumeration.
Now the problem is that I can't access foo() method using dynamic approach. But when I do static polymorphism like Manager manager = new Manager() I can access it.
What is the particular reason of this behavior. Is my design correct? What would be a better design? And which design pattern should I use?
There is no need to have the Type enum, the class itself (i.e. Intern) represents the employee type.
Related to the issue of not being able to call manager.foo() is because from a variable of a specific type you can call only those methods which are declared on that type (class).
In your case, when you declare Employee manager = new Manager("Ali", 1); you can call methods which are declared on Employee, in this case foo() is declared on Manager class
When you do Employee manager = new Manager("Ali",1); even though you are creating a Manager instance but the type is Employee, since the type is Employee the compiler do not know manager.foo(); is.
So you have to defile a void foo() method it can be abstract also.

How the code is working here in the subclass?

package practice;
class person{
private String firstname;
private String lastname;
public person(String firstname,String lastname){
set_first(firstname);
set_last(lastname);
}
public String get_first() {
return firstname;
}
public void set_first(String firstname) {
this.firstname=firstname;
}
public void set_last(String lastname) {
this.lastname=lastname;
}
public String get_last() {
return lastname;
}
}
class employee extends person {
private int empid;
public employee(String firstname, String lastname, int empid) {
super(firstname,lastname);
set_empid(empid);
}
public void set_empid(int empid) {
this.empid=empid;
}
public int get_empid() {
return empid;
}
}
class testing_super_keyword {
public static void main(String args[]) {
employee emp=new employee("Paul","Anderson",1234);
System.out.println(emp.get_first()+" "+emp.get_last());
System.out.println(emp.get_empid());
}
}
I got two classes here person superclass and employee subclass. So i just wanted to know this code isn't supposed to work as the firstname and lastname variable is private in superclass? But how the subclass i.e employee is inheriting those members and using it??
I thought private variable of superclass cant be inherited so how come it works fine here?
I am totally confused please help......
Although, the private variables of parent class are not inherited by child class i.e employee but there are public functions that are called getter and setter that allows to access the private members of class from its sub-class.
public String get_first() {
return firstname;
}
public void set_first(String firstname) {
this.firstname=firstname;
}
public void set_last(String lastname) {
this.lastname=lastname;
}
public String get_last() {
return lastname;
}
You see when you want to access firstname from parent, you'll call get_first() from employee object to get the firstname. If you want to set the firstname you'll call set_first("name") to set the name. Hope it might help.
private variable of superclass cant be inherited
Yes, you are absolutely right, they won't be inheriting. But in your code, you are not accessing those fields directly right?
public employee(String firstname,String lastname,int empid){
super(firstname,lastname);
set_empid(empid);
}
Here you are passing parameters (from the main method) to your employee constructor, the names of parameters are similar to the fields in person, but they are not the same. You can change parameters names like this and it will still work fine.
public employee(String fName, String lName,int empid){
super(fName,lName);
set_empid(empid);
}
Here the parameter values are taken into super class constructor and its private fields are initialized and then empid of employee is initialized.
System.out.println(emp.get_first()+" "+emp.get_last());
System.out.println(emp.get_empid());
Here also you are not accessing the private fields directly, you are calling the public methods which will be inherited to the employee and can be called on its reference.
Keeping members of a class as private and their behaviours (methods) as public is a part of encapsulation, so that you cannot directly access then but can set and get its value using public methods.
PS : Try to make the getters and setters using the IDE, if it gives the option and try to follow naming conventions for classes and methods.
lets review how firstname and lastname are being initialized here:
in subclass constructor firstname, lastname has been taken
then in the body of constructor by super(firstname,lastname), firstname and lastname pass to the parent (i.e. Person) to be taken care of.
so assume we are now in the parent constructor (Person) so, By calling set_first(firstname) and set_last(lastname) , parameters firstname and lastname is being set in parent class itself with the values which passed from the child constructor (i.e. Employee)
Regarding this description there is no violation.
The violation happens if you want to initialize private variable directly in Employee class as :
public employee(String firstname,String lastname,int empid){
this.firstname=firstname; //Violation
this.lastname=lastname; //Violation
set_empid(empid);
}

Java overriding method Error

basically I created a Person class and a constructor which sets the name,last name,age of the Person.all the properties of the class were set the private as it should be. I have made setters and getters for all the properties. On the main method I tried to override one of the setters just for practice reason. Its did draw an error saying Person.name not visible which means it cannot access private, Why this is happening, I mean if wasn't overriding the method it would have access. but if I set it to protected mode i will work.
Here is the code:
class Person {
private int age;
private String name;
private String last_name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public Person(int age, String name, String last_name) {
this.age = age;
this.name = name;
this.last_name = last_name;
}
}
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person per = new Person(15,"bb","Sb") {
public void setName(String name) {
this.name = "aaaa";
}
};
per.setName("asdfaf");
System.out.println(per.getName());
}
}
A private member is only accessible in the class in which it is declared.
You created an anonymous sub-class of Person and tried to access a private member of the super-class from the sub-class. This is never allowed.
When developers of a class wish to allow access to certain members of the class to its sub-classes, they set the acess level to protected.
You have created a class named Person and in the following lines you are trying to create an anonymous subclass:
Person per = new Person(15,"bb","Sb") {
public void setName(String name) {
this.name = "aaaa";
}
};
As mentioned in doc:
A subclass does not inherit the private members of its parent class
Here your anonymous subclass is trying to access private field name directly and so is the error. You can use getter/setter which are public. You can also check this related question on SO.
You cannot access private fields from outside your class, even if you are overriding it. You are basically defining a new subclass of Person in your main(), which isn't allowed access to the private field Person.name. However, it can access a protected field.
Basic idea behind overriding is to redefine existing functionality and give new definition to it. If you refer to documentation, private member variables are only accessible in it own class. That why it is not available in your anonymous sub-class implementation.
Note: Generally we do not override setter methods as they are not a functionality.
This is called encapsulation . You can not access private vars from other classes . you can find more description here

Programming difference between POJO and Bean

I have the following two classes. Can I say the first one is a POJO class and the second one as a Bean class?
1) POJO class, since it has only getter and setter method, and all the member are declared as private
public class POJO {
private int id;
private String name;
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId() {
this.id = id;
}
public void setName() {
this.name = name;
}
}
2) Bean class - all the member variables are private, has getters and setters and implements Serializable interface
public class Bean implements java.io.Serializable {
private String name;
private Integer age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
}
It also has a no-arg constructor.
Only difference is bean can be serialized.
From Java docs - http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.
the JavaBean class must implement either Serializable or Externalizable, must have a no-arg constructor,all JavaBean properties must public setter and getter methods (as appropriate)
all JavaBean instance variables should be private

Categories