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);
}
Related
I have a parent class that has 2 private instance fields but my child class which has no instance fields 'magically' creates 2 instance fields.
public class Parent
{
private String firstName;
public String lastName;
private int age;
public Parent()
{
System.out.println("No-Parameter Constructor");
}
public Parent(String firstName, String lastName, int age)
{
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String toString()
{
return "firstName: " + firstName + " lastName: " + lastName + " age: " + age;
}
public String getFN()
{
return firstName;
}
}
public class Student extends Parent
{
public Student(String firstName, String lastName, int age)
{
super(firstName, lastName, age);
}
public static void main(String[] args)
{
Parent p = new Parent("Logi", "Tech", 42);
Student s = new Student("Logi", "Camera", 21);
System.out.println(p);
System.out.println(s);
System.out.println(p);
System.out.println(p.getFN());
}
}
Output:
firstName: Logi lastName: Tech age: 42
firstName: LogiStudent lastName: Camera age: 21
firstName: Logi lastName: Tech age: 42
LogiStudent
You are not accessing private fields from the Student class. Just look at your code - nowhere in the body of class Student extends Parent {} do you refer to those fields in any way.
class Student extends Parent is java-ese for: "Let's define this new concept called Student. Begin by taking absolutely every single last thing Parent has, and then bolt, on top of all that, a few more things".
In other words, if Parent has the field 'age, then so does Student.
accessibility is almost entirely unrelated to this notion; accessibility (private) is about which code (NOT which instance!!) is allowed to directly interact with things. Given that the age field is private, whilst every instance of Student has that field, the code located in Student.java cannot touch that field directly. It is of course free to invoke a method that its superclass does allow access to (such as the toString method which is public) and then observe as IT touches those fields. That's not 'direct access', that's indirect, and that is fine.
Similarly, Student can invoke getFN() anywhere it wants, and thus get the first name. It cannot, however, set the firstname, unless Parent decides to add a void setFirstName(String fn) { this.firstName = fn; } method, of course.
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.
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
I have always been programming in java, and recently i started learning some c++.
In C++ it is conventional to set setter params as const, why don't we see this as much in java ?
I mean are there any disadvantages to creating a setter like so:
public void setObject(final Object o){ this.o=o; }
vs
public void setObject(Object o){ this.o=o; }
The first one should enforce for Object param o to stay constant through the whole set function, not ?
Edit:
A final param would enforce this NOT to happen :
public void setName(String name){
name="Carlos";
this.name=name;
}
The user will never be able to set the name different from "Carlos"
There's little advantage to setting a Java method parameter as final since it does not stop someone from changing the parameter reference's state within the method. All it prevents is the re-assignment of the parameter variable to something else, which does nothing to the original reference, and it allows for use of the parameter in anonymous inner classes. If you wanted true safety in this situation, you'd strive to make your parameter types immutable if possible.
Edit
You've posted:
public void setObject(Object o){
o++; // this does not compile
this.o=o;
}
Which mixes primitive numeric and reference type. It only makes sense if o is an Integer or other numeric wrapper class, and even so, making it final would not prevent someone from creating:
private void setI(final Integer i) {
this.i = 1 + i;
}
But neither your code nor this code above would affect the parameter object on the calling code side.
Edit
OK now you've posted:
public void setName(String name){
name="Carlos";
this.name=name;
}
But then someone could write
public void setName(final String name){
this.name= name + " Carlos";
}
Here's where the danger comes and where final doesn't help. Say you have a class called Name:
public class Name {
private String lastName;
private String firstName;
public Name(String lastName, String firstName) {
this.lastName = lastName;
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
And then a class, Foo, with a Name field and a setter. This is dangerous code:
class Foo {
private Name name;
public void setName(final Name name) {
name.setFirstName("Carlos");
this.name = name;
}
}
Because not only does it change the state of the field, it changes the state of the Name reference in the calling code, and the final modifier won't help one bit. The solution: make Name immutable.
e.g.,
import java.util.Date;
// class should be declared final
public final class BetterName {
private String lastName;
private String firstName;
private Date dateOfBirth;
public BetterName(String lastName, String firstName, Date dob) {
this.lastName = lastName;
this.firstName = firstName;
// make and store a private copy of non-immutable reference types
dateOfBirth = new Date(dob.getTime());
}
// only getters -- no setters
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public Date getDateOfBirth() {
// return copies of non-immutable fields
return new Date(dateOfBirth.getTime());
}
}
Okay, a final parameter/variable cannot be assigned to. As the java compiler needs to be capable to determine if a variable/parameter is actually final (for anonymous inner classes), optimization is no factor AFAIK.
It is more that C++ has a larger tool set, which java tried to reduce. Hence using C++ const string& is important, saying
The string is passed by pointer, access is automatically dereferenced.
If the actual argument is a variable, the variable itself is not changed.
Mind there might be a conversion operator for passing something else than a const string&.
Now java:
Java does not allocate objects on the stack, only keeps primitive types and object handles on the stack.
Java has not output parameters: a variable passed to a method call will never change its immediate value.
Back to your question:
As a setter in java mostly would not benefit from a final parameter.
A final will be a contract to not use the variable for a second assignment.
However:
public final void setXyz(Xz xyz) {
this.xyz = xyz;
}
is more useful: this method cannot be overriden, and hence may be safely used in a constructor. (Calling an overriden method in a constructor would be in a context of a still not initialized child instance.)
What I am trying to do is access information (variables, methods, etc) from a superclass and it's subclasses.
If, what I know about inheritance is right, by accessing the superclass we have access to it's subclasses by default. So I am thinking that I only need to be able to access the parent (super) class.
But how do I do that?
I am not going to post all the code up here, and that will turn this post into 3 pages.
The superclass is just a general code to create a contact and the class that needs to access the superclass is a class that creates an arraylist and records each contact in the arraylist.
I am not trying to get the code written for me, but all the help to understand how this will work, will be greatly appreciated.
To keep this short, I won't post the subclasses unless needed.
Contacts (Superclass):
public class Contacts
{
protected String fname;
protected String lname;
protected String email;
protected String phone;
public Contacts(String fname, String lname, String email, String phone)
{
this.fname=fname;
this.lname=lname;
this.email=email;
this.phone=phone;
}
public String getfname()
{
return fname;
}
public void setfname(String first)
{
this.fname=first;
}
public String getlname()
{
return lname;
}
public void setlname(String last)
{
this.lname=last;
}
public String getemail()
{
return email;
}
public void setemail(String e)
{
this.email=e;
}
public String getphone()
{
return phone;
}
public void setphone(String num)
{
this.phone=num;
}
public String getFullName()
{
String full=fname+" "+lname;
return full;
}
I haven't done much on this code because I have been trying to figure it out without really knowing where to start. I do not think the arguments should be null, I just included those to satisfy the evil compiler.
Addressbook:
import java.util.ArrayList;
public class AddressBook
{
Contacts enteredContact = new Contacts(null, null, null, null);
}
Here is one of the subclasses to get an idea of what is included.
Friends (subclass):
public class Friend extends Contacts
{
private String dob;
/**
* Constructs a new Friend object. (Insert any further description that is needed)
* #param fname
* #param lname
* #param email
* #param phone
*/
public Friend(String fname, String lname, String email, String phone)
{
super(fname, lname, email, phone);
}
/**
* #return the dob
*/
public String getDob()
{
return dob;
}
/**
* #param dob the dob to set
*/
public void setDob(String dob)
{
this.dob = dob;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString()
{
return fname+", "+lname+", "+email+", "+phone+", "+dob;
}
}
If what I know about inheritance is right, by accessing the superclass
you have access to it's subclasses by default.So I'm thinking I only need to be able to access the parent (super) class.
No , by accessing the superclass you have access to only those methods of sub-class which is overridden by sub-class . The methods which the sub-class creates for own even if it is public couldn't be accessed by the object of superclass.
If a class extends a superclass, it inherits all of its members. The non-private ones it can access directly.
FYI you can use the super() constructor to initialise the fields.
public class AddressBook {
public AddressBook(String fname, String lname, String email, String phone) {
super(null, null, null, null);
}
}
Use super function/keyword to access parent class. You can call a parent method like this
super.methodName();
To access parent constructor, you can do it in the following way using super() method.
super(null, null, null, null);
If what I know about inheritance is right, by accessing the superclass
you have access to it's subclasses by default.
No, this is backwards. By accessing the subclass, you have access to the fields of the superclass, limited to the visibility and finality of the field. You can use super() to access them as you need to.
Think of inheritance like a family tree. The superclass is your parent. Your parents can't access any of your private fields, but you've inherited quite a few of them from yours.
I'm seeing a basic misunderstanding of what superclass and subclass are.
It seems to me that you're under the impression that the subclasses of Contacts are fname, lname, etc?
These are called members, or more properly in this case: instance members.
A subclass would be a class which extends Contacts, like so:
public class ContactsSubclass extends Contacts {
...
}