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 ;)
Related
Eg
class Abc{
public void fun()
{
System.out.println("public method") ;
}
#Override
public String toString()
{
// "has to be public method but the access is default because of the class access";
return super.toString();
}
}
In the above Eg - fun method access is public but the class access is default hence what is the use of having the method public rather than default because it cannot be access without creating object.
In the same way the toString method has to be public since (overriding cannot restrict the access). But it is already getting restricted since the class access is default
My Basic question is
What is the use of having a less restricted method in a more restricted class?
My Basic question is What is the use of having a less restricted method in a more restricted class?
There are several purposes related to inheritance and polymorphism. The biggest of those is probably that methods that override superclass methods or implement interface methods cannot be more restricted than the method they override. In this regard, I note that you express a possible misconception when you say:
the toString method has to be public since (overriding cannot restrict the access). But it is already getting restricted since the class access is default
That class Abc has default access does not prevent any other class from having references to instances of Abc or from invoking the public methods of that class. The declared type of any such reference will be a supertype of class Abc, but the implementation invoked will be that provided by Abc.
Additionally, there is the question of signaling intent. It is helpful to view the access specified for class members to be qualified by the access level of the class. Thus, declaring fun() to be public says that it can be accessed by everyone who can access an instance of Abc. This is somewhat useful in its own right, but it also turns out to be especially useful if the access level of the class is ever changed. If the class's designer chose member access levels according to this principle, then those do not need to be revisited under these circumstances.
On its face?
Absolutely no purpose whatsoever. It's measurable (you can use reflection to fetch a java.lang.reflect.Method object that represents that method, and you can ask it if it is public, and the answer would be 'yes', but it doesn't actually change how accessible that method is.
However, taking a step back and thinking about the task of programming in its appropriate light, which includes the idea that code is usually a living, breathing idea that is continually updated: Hey, your class is package private today. Maybe someone goes in and makes it public tomorrow, and you intended for this method to be just as public as the type itself if ever that happens.
Specifically in this case, you're overriding a method. Java is always dynamic dispatch. That means that if some code has gotten a hold of an instance of this class (Created with new Abc()), and that code is not in this package, that they can still invoke this method.
Let's see it in action:
package abc;
class Abc {
#Override public String toString() { return "Hello"; }
}
public class AbcMaker {
public Object make() { return new Abc(); }
}
Note that here AbcMaker is public and make() can be invoked just fine from outside code; they know what Object is, and Abc is an Object. This lets code from outside the abc package invoke and obtain Abc instances, even though Abc is package private. This is fine.
They can then do:
package someOtherPackage;
class Test {
public void foo() {
System.out.println(new AbcMaker().make().toString());
}
}
And that would print Hello, as expected - that ends up invoking the toString defined in your package private class, invoked from outside the package!
Thus, we come to a crucial conclusion:
That toString() method in your package private class is ENTIRELY PUBLIC.
It just is. You can't override a method and make it less accessible than it is in your parent type, because java is covariant, meaning any X is a valid standin for Y, if X is declared as X extends Y. if Y has public toString, then X's can't take that away, as all Xs must be valid Ys (and Ys have public toString methods, therefore Xs must also have this).
Thus, the compiler is forcing you here. The banal reason is 'cuz the spec says so', but the reason the spec says this is to make sure you, the programmer, are not confused, and that what you type and write matches with reality: That method is public, it has to be, so the compiler will refuse to continue unless you are on the same page as it and also say so.
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..
Is there an info-graphic that explains java variable inheritance and constructor code flow?
I'm having troubles visualizing how inheritance and class variables work, public, static private default or otherwise.
The Java Tutorials from Oracle have a section all about Inheritance and should be able to answer most of your questions.
I would refer you to go with Lava Language Specification and try to write the code using above keywords and then test it.
default: Visible to the package. .
private: Visible to the class only
public: Visible to the world
protected: Visible to the package and all subclasses .
The access modifier (public, protected, package) plays only a small role in inheritance. You can't make a function or variable in a subclass less accessible than the superclass (e.g., Animal has public void doStuff() and Cat extends Animal has private void doStuff()
Static and non-static methods don't really affect inheritance either. Static variables work the same way, except relative to the class of interest
public class Magic{
public static int pants;
}
public class MagicPants extends Magic{
public void go(){
System.out.println(pants);
System.out.println(MagicPants.pants);
System.out.println(Magic.pants);
}
public static void main(String argv[]){
Magic.pants = 2;
MagicPants.pants = 1;
new MagicPants().go();
}
}
All print 1
Constructor code flow is easy - follow the super() calls.
So i don't know graphics.
Static means the variable is the same for all object which have the same class.
Like
public Class TryVariable{
public static int variable = 2
public static void main(String[] args){
a = new TryVariable()
b = new TryVariable()
system.out.println(a.variable)
system.out.println(b.variable)
// both equals 2
a.variable= 3
system.out.println(a.variable)
system.out.println(b.variable)
// both equals 3, because variable is static.
}
Public variable means you can directly change directly her by the way i do in ma previous example: object.variableName = value.
This is dangerous, all people inadvisable to use it.
Private variable can't be change directly you need to use somes getters and setters to do this work. It's is the good way to code.
The defaut, i'm not sur of all parameters so i don't describe to you. But 99.9% of time the private is use.
Protected mean, the variable is open to packages and sub classes (in first time private is easier to use and safer)
An other parameter can be final, with this parameter the variable can't be change any more. It's like a constant. And a static final parameter is a class constant.
If you need more information, previous response explain where are find the officials sources.
This is very easy example: http://vskl.blogspot.cz/2009/05/polymorphism-in-java.html
every time you create Circle or Square object, Shape object is created too
About the variables:
- private fields are not accessible by any other class including subclasses.
- protected fields are accessible by any subclass. Taken the picture from the link, variables x and y of abstract class Shape, every instance of Circle or Square have these fields.
- default fields are accessible by any subclass and by any class in the same package(only in same package, classes in subpackages do not have access). This is useful typicaly when writing automated test, you don't have to declare public getter for the field.
- public fields are accessible by any other class. However using those is not a clean way how to write code, it is better to create private field with getter and setter.
- static keyword designates field owned by class, not by it's instances. It is like having one field shared by multiple instances of the class. If one instance changes value of this field, every other instance can read only this new modified
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();
}
I have code very much like the following.
package my.pkg;
public abstract class X {
private CapableField field;
public abstract void doSomething();
public X(CapableField fieldValue) {
this.field = fieldValue;
}
}
And:
package my.pkg.sub;
public class Y extends my.pkg.X {
public void doSomething() {
this.field.doSomething();
}
}
Why is this even legal code in Java? I thought "private" meant that the field will not be directly accessible in subclasses, and that this was a fairly basic tenet of class inheritance. Making X concrete instead of abstract changes nothing.
What do I do if I specifically want a field, or member function, to be accessible only inside the class where it is defined, and not in some random subclass of the defining class?
This is not true. Most likely you've actually definied Y as an inner class. This way the private fields of the outer class are indeed visible like that.
Doesn't compile for me too! I suspect your Java implementation.
This is impossible. May be you missed something when you explain your question.
private members are not visible in inheritance except in inner class scope. If you want them to be accessed by the subclass then declare them as protected. or use setters and getters.
and in your code you used package keyword in your package declaration which is not allowed and gives compilation error.
Make sure that your classes in two different files. for example X.java and Y.java and y not an inner class