Reputation:
I was doing some reading here. The user suggested that
if you plan on subclassing and want the validation setter available, declare it protected final instead of private.
why declare a method protected final when I could declare it private and have the constructor in the base class set the variables.
Example:
public class Person {
private String firstName;
private String lastName;
public Person(String firstname,String lastname) throws InvalidDataException
{
setFirstname( firstname);
setLastname(lastname);
}
public void personFirstName(String firstName) throws InvalidDataException {
setFirstname(firstName);
}
public void personLastName(String lastname) throws InvalidDataException {
setLastname(lastname);
}
public String getFirstName() {
return firstName;
}
public String getlasttName()
{
return lastName;
}
private void setFirstname(String firstname) throws InvalidDataException{
if( firstname == null ||firstname.length() < 1) {
throw new InvalidDataException("First Name Cannot be Empty");
}
this.firstName=firstname;
}
private void setLastname(String lastname) throws InvalidDataException {
if( lastname == null ||lastname.length() < 1) {
throw new InvalidDataException("Last Name Cannot be Empty");
}
this.lastName = lastname;
}
}
public class Professor extends Person {
private String professorID;
public Professor(String professorID,String firstname, String lastname) throws InvalidDataException {
super(firstname, lastname);
// TODO Auto-generated constructor stub
setProfessorID(professorID);
}
public void setID(String professorID) throws InvalidDataException{
setProfessorID(professorID);
}
public String getID()
{
return this.professorID;
}
private void setProfessorID(String ID) throws InvalidDataException{
if( ID == null ||ID.length() < 1) {
throw new InvalidDataException("ID Cannot be Empty");
}
this.professorID=ID;
}
public void printData()
{
System.out.println("Professor ID: " + this.getID() + " First Name: " + this.getFirstName() + " Last Name: " + this.getlasttName());
}
}
In what situation would I want to declare the private methods in Person to be protected final? My subclass Professor can access them through the constructor in the base class.
Upvotes: 1
Views: 147
Reputation: 1482
Besides extending, the use for protected
can be for Managing Classes.
See, protected
does not mean only a child class has access to the field in question. But any class within the same package.
Say you have an abstract class Entity
And another class SpecificEntity1 extends Entity
And another class SpecificEntity2 extends Entity
but you want a way to keep track of all entities.
What you do is you make the constructors for the specific classes protected
put all of the classes in the same package and create another class in that package like EntityManager
with a createEntity
method. that way you can only create your entities using that class outside of the package.
Upvotes: 1
Reputation: 476554
That's for the case where the subclass should be able to set the value. Since you can't foresee the subclasses, you better make the assumption that all values can be set by a third value. For instance in some culture's a women takes the name of her husband. For instance:
public class Women extends Person {
public void marry (Person person) {
setLastName(person.getLastName());
}
}
The book probably suggests not to make the field protected, after all each class must guarantee that its own state is valid. By thus rewriting a validator yourself, you could invalidate the state from the super class point of view.
It is for instance reasonable to assume that a persons name doesn't contain digits. You can implement this logic in the setter-validator. If you however declare the field protected
, one could overrule this.
Making the method public
, as you did, is probably not adviseable, at least not in a general case. That would imply every object has the right to set a persons name.
Upvotes: 1
Reputation: 27336
protected
The protected
key word is an access modifier that allows subclasses to access this resource. In this case, the method.
final
The final
key word is a polymorphic restriction that prevents subclasses from redefining a given resource. Again, in this case, the method.
With these definitions in mind, this creates a validation method that the subclass can still access without being able to change it. In short, no subclasses can violate the terms of the validation. By just putting the calls in the constructor, this means that subclasses can not make validation calls anywhere else. They have to create a new object every time they want to test, which is obviously not desirable.
Doing it this way makes it more testable, but allows subclasses as much flexibility as they should be permitted while not breaking the validation rules.
Upvotes: 3