Accessing protected variables in the super class - java

I have recently joined a new company and I am trying to get used to their coding style guidelines. I have no problem changing my coding style, but one particular point, I am not sure whether they are right or not.
For my first task I had to extend one of the existing abstract classes to develop a particular functionality. Thus I needed to access many attributes declared in this abstract superclass. To do so I proposed to change the visibility of these attributes and declare them as protected. My surprise came with their reply:
"Never! That is absolutely against OOP and you would produce obscure and difficult to maintain code! What you have to do is creating a getter in the super class and using it from the subclass in order to access these attributes".
Well, I have been always using protected attributes in an abstract superclass and accessing them from the subclass directly and I always thought there was nothing wrong with it. Even I would say that calling all the time the getter to access an attributes in the super class is slower than using it by its name...
What do you think about it? Is it normal/standard coding style declaring the attributes in a superclass and accessing them directly or are you of the oppinion that is better creating getters for these attributes.
To sumarize, my way:
public abstract class A {
protected String variableA="a";
public abstract methodToImplement();
}
public MyClass B extends A {
public methodToImplement() {
System.out.println(variableA.length());
}
}
Their way:
abstract class A {
protected String variableA="a";
public String getVariableA() {
return variableA;
}
public abstract methodToImplement();
}
MyClass B extends A {
public methodToImplement() {
System.out.println(getVariableA().length());
}
}
Thanks.

So as other threads already point out it appears to be so that it's indeed recommended to use getters and setters. The reason being that if you ever plan to change the representation of that value (StringBuilder instead of String for example) you will have to change your code. A getter/setter allow you to program in a way that you send the getters/setters the data you want, and they will store it in the proper field for you (e.g., appending it to the StringBuilder). So yes, it apears to have a lot of advantages, even though it's not your coding style. However, declaring the variable as protected seems pretty weird when you use a getter and a setter as well..
I personally try to avoid getters/setters when they are a bit of overkill. To me they are overkill for value variables. For reference variables they are however a good idea.
However, I think there is no right or wrong here..

Related

Variable with same name in subclass and superclass

I'm currently working on some Findbugs issues of another persons project.
This is the issue I'm working on:
Correctness - Class defines field that masks a superclass field
This class defines a field with the same name as a visible instance field in a superclass. This is confusing, and may indicate an error if methods update or access one of the fields when they wanted the other.
There is the superclass OutputInterface and the subclass CoreOutputInterface which extends OutputInterface. Both of them define the variable className.
CoreOutputInterface has some subclasses as well.
To fix the issue I would simply remove the className from the subclass (CoreOutputInterface) since it is already defined in the superclass.
The variable is never read or set with super.className or this.className, only with className, so in my opinion it should not lead to any problems.
Also the variable from the superclass is never referenced in the whole project (I checked it with the Eclipse reference function).
Can anyone confirm that this can not lead to a problem in any situation?
Thanks in advance for your help.
OutputInterface:
public abstract class OutputInterface {
protected String className = null;
...
}
CoreOutputInterface:
public abstract class CoreOutputInterface extends OutputInterface {
protected String className = null;
...
public void getClassName() {
return className;
}
public void setClassName(String newName) {
className = newName;
}
...
}
Yes, remove the declaration from the subclass. And provide/leave as they are in the example above a getter and, if needed, a setter. If the field's never used, it may simply have been overlooked, when 'CoreOutputInterface' was created, as the developer might have copy-pasted 'OutputInterface' and then edited it accordingly.
More theoretically, this is or could become, depending on the complexity and usage of the class, an example of broken Liskov substitution principle of the known SOLID OOP design principles. It states that superclass objects must be at all times replacable with their subclass counter-parts. Given there is a difference between both 'className' fields in use, a method could falsely rely on one or the other and lead to undefined behaviour, as stated in the report.
However, I am more confused, why a 'class' is called an Interface.
If it was really an interface, we wouldn't have had the problem in the first place, as interfaces allow only for constants. In that case getter and setter would have been sufficient.
If it is really a class, then one should drop the "Interface" from the name. Otherwise, the faulty name only hinders understanding and could lead to unexpected side-effects in future.

Does using super to elevate a variable to an abstract super class provide a benefit over assigning it in a subclass?

For starters, I hope I have worded the question well enough. If not, please feel free to edit it or suggest changes.
I'm working through a Java textbook to help with my university course and I came across an exercise asking me to create an abstract class Airplane, with three subclasses, B747, B757 and B767. Each object of those three subclasses has a unique serial number.
Cutting out a lot of the other parts of the question (which I hope aren't relevant!), I did this:
public abstract class Airplane {
String serialNumber;
public String toString() {
return getClass().getName() + ": " + serialNumber
}
}
I then declared three subclasses, each of which looked like this:
public class B747 extends Airplane {
B747(String serial) {
serialNumber = serial;
}
}
Finally, in my main program, I instantiated new objects using the following code:
Airplane a = new B747("ABC101");
System.out.println ("Airplane a: " + a);
Now, the code works fine. However, when I looked at the answers in the book, they chose to do it a different way. They instantiated each object in the same way, but instead in each class had the following method:
public B747 (String serial) {
super (serial);
}
In the abstract superclass Airplane, they then had:
public Airplane (String serial) {
this.serial = serial;
}
Was this just a matter of personal preference, to elevate the String to the superclass and act on it there, or does this provide any benefits, whether security or otherwise?
Was this just a matter of personal preference, to elevate the String to the superclass and act on it there, or does this provide any benefits, whether security or otherwise?
It's only changing where the variable is accessed - not where it's declared. And it's a good thing:
Every Aeroplane should have a serial number, so it makes sense for the Aeroplane class to enforce that
It allows the field to be private (and final) within Aeroplane, with a "getter" to provide read-only access to it as widely as is required
Both parts are important - but if you're not sure about the first aspect, consider what would happen if you had another few subclasses. Do you really want the assignment to occur in every single subclass? There will always be a superconstructor call - whether implicit or explicit - but there's no reason to repeat the assignment.
I definitely prefer the book's solution to your one - particularly if they make the field private and final. In my code, I hardly ever use non-private fields, other than for constants.
Also the super() is just a call to the superclass constructor(Aeroplane), it's common practice when making a class hierarchy as (far as I know) that you call upon the superclass constructor. There are keywrods like "this" and "super" which defines if it is values in the super/sub(child) class in the hierarchy. Java usually knows if you simply write the field value name, but it's actually in secret putting the "this" part in there for you.

Change the access modifier of an overridden method in Java?

Is there a reason one can change the access modifier of an overridden method? For instance,
abstract class Foo{
void start(){...}
}
And then change the package-private access modifier to public,
final class Bar extends Foo{
#Override
public void start(){...}
}
I'm just asking this question out of curiosity.
Java doesn't let you make the access modifier more restrictive, because that would violate the rule that a subclass instance should be useable in place of a superclass instance. But when it comes to making the access less restrictive... well, perhaps the superclass was written by a different person, and they didn't anticipate the way you want to use their class.
The programs people write and the situations which arise when programming are so varied, that it's better for language designers not to "second-guess" what programmers might want to do with their language. If there is no good reason why a programmer should not be able to make access specifiers less restrictive in a subclass (for example), then it's better to leave that decision to the programmer. They know the specifics of their individual situation, but the language designer does not. So I think this was a good call by the designers of Java.
Extending a class means the subclass should at least offer the same functionality to the other classes.
If he extends that, then it is not a problem.
Extending could be be either adding new methods or by offering existing methods to more classes like making a package-access method public.
There is only one, you might want the override to be visible by more classes, since no modifier is default, public broadens that.
The explaination is this:-
It's a fundamental principle in OOP: the child class is a fully-fledged instance of the >parent class, and must therefore present at least the same interface as the parent class. >Making protected/public things less visible would violate this idea; you could make child >classes unusable as instances of the parent class.
class Person{
public void display(){
//some operation
}
}
class Employee extends Person{
private void display(){
//some operation
}
Person p=new Employee();
Here p is the object reference with type Person(super class),when we are calling >p.display() as the access modifier is more restrictive the object
reference p cannot access child object of type Employee
Edit: OK, I changed my answer to fix the problem.
If that couldn't be done, then there would be some cases where a class wouldn't be able to implement an iterface and extend a class because they have the same method with different access modifiers.
public Interface A {
public void method();
}
public abstract classs B {
protected void method();
}
public class AB extends B implements A {
/*
* This would't be possible if the access modifier coulnd't be changed
* to less restrictive
*/
public void method();
}

inheritance: accessing array from super class to search it

I have a superclass Trail that populates an array myList[]. I want a subclass TrailSearch to access myList[] and search it. How can i do this? I know i could simply pass the array to the TrailSearch class as an argument but i'm trying to get to grips with inheritance so i thought i try it the hard way but i need some tips.
PSEUDO CODE
class Main{
new Trail trailObject
new TrailSearch tsearchObject
tsearchObject.methodSearchMyList()
}
class Trail{
constructor Trail(){}
methodPopulateMyList(){
// populate myList[] }
}
class TrailSearch extends Trail{
constructor TrailSearch(){}
methodSearchMyList(){
// search myList[] }
}
that's more or less how i would approach it but what are the rules to make this inheritance idea work?
Inheritance is the wrong way to solve this problem, and this is the wrong problem to use if you are trying to get to grips with inheritance. TrailSearch is not a Trail so shouldn't inherit from it.
A better solution to this problem is the visitor pattern: http://en.wikipedia.org/wiki/Visitor_pattern
Also see
http://msdn.microsoft.com/en-us/library/27db6csx%28v=vs.80%29.aspx for a brief explanation of the "Is A" relationship which implies inheritance.
As long as the myList[] array is not declared private your subclass can access it directly.
Try to define myList[] as a protected variable in class Trail, then you can access the variable from your subclass also
In java, for each field and method, you must declare the visibility. This will determine who can access this field or this method. Visibility is declared with a keyword, which is one of these :
public : The field or method can be accessed from everywhere
private : Only the class where the field / method is declared can access it
protected : Only the class and its subclass can access the field / method.
There's a fourth visibility, called the "package visibility" which takes place when no keyword is specified : the field / method can be accessed within the same package. This visibility isn't used very often.
Here's a little example :
public class A {
public int var2; // this is a public variable
protected int var3; // this is a protected variable
private int var1; // this is a private variable
public void test() { } // this is a public method
protected void test3() { } // this is a protected method
private void test2() { } // this is a private method
}
You can see in my little example, that my class also has a visibility, the exact same rules as for fields and methods are used, only for instantiation instead of accessibility.
In your case, there's two different solution to allow access to your field from the subclass :
declare the field as public, protected or without visibility (ie package visibility)
declare the field as private, and add a setter, getter or others access methods. This is the preferred method and it is called encapsulation.
Since this is probably a homework, I won't provide code to you, it will be a good exercise to write it yourself.
PS: I know that encapsulation is a little more than just what I explained, but dropping the name like that won't hurt the OP ;)

What does it mean for a method to be public/private/other in java? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What does it mean for a method to be public/private/other in java?
What are the advantages and disadvantages of these options?
What is my impetus, as someone trying to be a good programmer, to care?
When a method is public it means it can be accessed by other objects
For instance:
class David {
// public method, can be use by anyone
public String getName() {
return "David";
}
}
The method getName may be accessed by other classes because it is public:
class Other {
David davidOne = new David();
String davidsName = davidOne.getName(); //<-- compiles and runs
}
The advantage.. well you can use it from other places.
When a method is private it means it can only be accessed by objects OF THE SAME CLASS
For instance, in this new definition:
class David {
public String getName() {
return "David";
}
// private method... nobody but David's "instances" can use it..
private int getAge() {
return 19;
}
}
The method getAge can't be accessed by other classes because it is private, if you try to do it, the compiler will give you an error message:
class Other {
David davidOne = new David();
String davidsName = davidOne.getName();
int davidsAge = davidOne.getAge(); //<-- Compiler error, getAge() is not visible
}
But, if you can use it within David class:
class David {
public String getName() {
return "David";
}
// private method... nobody but David's "instance" can use it..
private int getAge() {
return 19;
}
// Here the call to "getAge()" will succeed, because it is visible
// inside the class
public boolean hasSameAgeAs( David otherDavid ) {
return this.getAge() == otherDavid.getAge();
}
}
The advantage? You can create a bunch of methods and keep them private, avoiding data corruption or in general preserving your objects encapsulated
About encapsulation
In OOP ( object oriented programming ) the intention is to model the software after real life objects.
Real life objects have ( among other things ) attributes and methods to access those attributes.
You want to make public some of those methods, and keep private others.
For instance, a Human being, have a heart. But it is not exposed to everybody, it would be dangerous. It is encapsulated inside our body.
If we were to model a software after a real Human we may declare the method: heartBeat as private ( so, nobody can access it )
In the other hand, it would be useful to have come public methods like getGender to find out if your Human instance is male or female.
There are other access modifiers such as: "protected" and package protected ( whose doesn't have a keyword )
class David {
// protected method
protected int getBalance() {
return 1000000;
}
// package protected or "default" method
boolean knowsOop(){
return true;
}
}
There the method getBalance can only be accesed by David instances and David subclasses ( create another thread for what is a subclass )
The method knowsOop can be accesses by anyone inside the package as David is defined.
Don't worry about this two access modifiers, they will make sense when you learn more about OOP and Java.
Finally you should really, really take time to read:
http://java.sun.com/docs/books/tutorial/java/javaOO/index.html
I hope this helps
A public method can be accessed from everywhere, a private method only from the same class. The main advantage is the control over the API of an class. If I make only public what is needed, I can change the internal behaviour of a class , without breaking code depending on this class. You should care, because software changes often in the real world (at least it's my experience and others have it too) and the more every change breaks, the more energy you have to put into maintenance or the more bugs your software has. In the end it's a question of costs.
The possibility to hide internals of your class from users of this class to avoid breaking code by later changes is often called encapsulation or information hiding.
The two options besides public and private are package (without an modifier) and protected. The package-accessible method can also be accessed from within classes of the same package. I cannot remember to used that option in any useful way. protected methods can be accessed from classes, that inherit the class in question. That is often used to create classes with concrete behaviour for a defined API of the base-class. For example could you implement a new List-class by extending AbstractList and you only need to implement get and size (and one set-method for modifiable lists). The other methods exposed by the API of List are defined in the base-class, calling the three other methods if needed.
Private methods can be called only inside the class. You can call public methods of your class anywhere in program. Methods without access modifier are meant to have package visibility scope (it's called default), so you can invoke it anywhere in package, where class is defined.
See http://en.wikipedia.org/wiki/Object_oriented_programming#Encapsulation
HThe public, protected and private modifiers control what other code can see those methods (or fields). It's about controlling the interface you're exposing.
The commonly useful ones are:
The public modifier: any other can see your method.
The private modifier: no code other than your class and any inner classes can see your method.
These would be useful for example if you wanted to ensure there was only a single instance of a class ever created (singleton pattern). You could make the constructor private, create a single instance and store is as a private member called instance, and provide a public method something like this:
public static MyObject getInstance() {
return instance;
}
and so you can guarantee that there will only every be one instance.
Update - another example as requested.
Another example might be where you have a complicated public method and you want to break it down into simpler parts. You could break it down into simplr methods, each doing part of the job, but you wouldn't want other code to call those part methods, as they wouldn't work on their own - so you would make the smaller methods private, ensuring that they can't be called outside your class.
the main reason is called encapsulation: don't give access to internal state of object.
For starters, I would to start restrict the access as much as possible. Start with private. If you happen to need the constructor, method or field from somewhere else, but cannot access it due to the restriction, then the next steps would be to ask yourself:
If it is a method, do you really need to access it? Does it change the behaviour of the class/instance? Shouldn't you let that class do the work? Shouldn't the current class (which needs that field or method) be brought tighter to that class?
If it is a field, do you need to get or set its value? Shouldn't you add a method which does exactly that?
Point 1 avoids wrong coupling and point 2 improves encapsulation. Once you've considered the above and concluded that less restriction is really needed, then set it one step or more further open.

Categories

Resources