Why access to filed and method differs in inherited class in Java? - java

class BaseClass {
protected int filed = 1;
public void method() {
System.out.println("+ BaseClass method");
}
}
class DerivedClass extends BaseClass {
private int filed = 2;
public void method() {
System.out.println("+ DerivedClass method");
}
public void accessFiled() {
System.out.println("DerivedClass: default filed = " + filed); // output 1
System.out.println("DerivedClass: upcasting filed = " + ((BaseClass)this).filed); // output 2
}
public void accessMethod() {
System.out.println("DerivedClass: default method");
method(); // output "+ DerivedClass method"
System.out.println("DerivedClass: upcasting method");
((BaseClass)this).method(); // expecting "+ BaseClass method" but "+ DerivedClass method"
}
}
Why the access to filed(data member) and method differs?Could you explain it to me on both language design and implementation details aspects?
thanks.

This happens because you can only override methods, not fields. In DerivedClass your hiding the variable filed declared in the BaseClass. An instance of DerivedClass really has 2 fields called filed and you can access both with the appropriate cast. It wouldn't make much sense being able to override fields... Only behavior.

Related

Constructor, subclass method called from base and instance member order initialization problem [duplicate]

This question already has answers here:
Initialize field before super constructor runs?
(7 answers)
Closed 4 years ago.
So, I'm trying to design a small base abstract class:
public abstract class BaseClass
{
abstract void reload();
protected BaseClass()
{
reload();
// schedule reload for every X minutes
}
}
Now, subclass:
class SubClass extends BaseClass
{
private int member = 5;
#Override
void reload()
{
member = 20;
}
}
Now, the problem I'm facing is that reload() method is called before the member is initialized. Thus, member is assigned 20 and afterwards, assigned with the value 5. (this is only an example of course, the actual code is different, but the same idea).
What is the best design for what I'm trying to achieve?
I want the order of the initialization to be - member assigned 5, and if reload() fails for some reason i want it to stay with the initial value. However in this code, 5 overrides the value of reload(). If I don't assign an initial value for the instance member, it works of course.
Is it possible what I'm asking?
Override the constructor and call reload() there but do not call super(), this might not be acceptable for other reasons :)
class SubClass {
private int member = 5;
public SubClass() {
reload();
}
...
}
You can use a builder to achieve that.
This way you can achieve full control.
public abstract class Foo {
public abstract void postConstruct();
public static void main(String[] args) {
Bar bar = Foo.build(Bar.class);
System.out.println(bar);
}
public static <T extends Foo> T build(Class<T> clazz) {
T obj;
try {
obj = clazz.newInstance();
obj.postConstruct();
return obj;
} catch (Exception e) {
throw new IllegalArgumentException(
"Class "+clazz.getName()+" is not a valid class",e);
}
}
}
public class Bar extends Foo {
int value = 10;
protected Bar() {
super();
}
public void postConstruct() {
value = 7;
}
#Override
public String toString() {
return "Bar [value=" + value + "]";
}
}

java inheritance setting value in parent class

I have an identical method that is repeated in every subclass and I'd like to refactor it to just one method in a superclass.
public class SubClass1 extends SuperClass {
private BoltHexHead bolt;
private void computeFoo() {
//Foo formula is identical in all subclasses. Need to move up
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
private void computeBar() {
//computeBar method in all subclasses but Bar formula is different amongst all subclasses
setBar(bolt.getDiameter() - 2*bolt.getPitch() - 3*bolt.getTpi());
}
private void computeSeparation() {
//computeSeparation method only exists for a Subclass 1
setSeparation(bolt.getLength() - 2*nut.getFlatDia());
}
public class SubClass2 extends SuperClass {
private BoltFlatHead bolt;
private void computeFoo() {
//Foo formula is identical in all subclasses. Need to move up
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
private void computeBar() {
//computeBar method here is different than in Subclass1
setBar(bolt.getDiameter() - 4*bolt.getPitch() - 1/3*bolt.getTpi());
}
private void computeProtrusion() {
//computeProtrusionmethod only exists for a Subclass 2
setProtrusionmethod(bolt.getThreadAngle() - 6*bolt.getTpi());
}
Initially I posted that bolt wasn't getting set in the SuperClass but was in the SubClass. What I got working after my initial post was the following
public abstract class SuperClass {
protected Bolt<?> bolt; <-- this was added but uses wildcard
...bolt getters/setter
protected void computeFoo() {
//Foo formula pulled up from all subclasses
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
}
public class SubClass1 extends SuperClass {
//private BoltHexHead bolt; <-- commented this out in each subclass
}
This is a JSF app and in each controller bean I instantiate the specific joint attribute subclass and then set the specific bolt. It was an earlier design decision to use setters for setting the bolt (and other properties) in the subclass rather than doing it with the Constructor; but one refactor at a time.
Controller for a Bolt Analysis using a HexHead Bolt
private SubClass1 sc1 = new SubClass1();
private BoltHexHead bolt;
sc1.setBolt(bolt);
sc1.computeResults();
Controller for a Bolt Analysis using a FlatHead Bolt
private SubClass2 sc2 = new SubClass2();
private BoltFlatHead bolt;
sc2.setBolt(bolt);
sc1.computeResults();
So my question is, is it OK to use wildcard Bolt<?> bolt or is there a better approach?
I'm just trying to put a identical/duplicate method from all my subclasses into the parent but one of the variables (bolt) isn't getting set
Thats because in java you cannot override fields.
So your variables "private B bolt;" in your superclass and "private BoltHexHead bolt;" in your subclass are two different things. They actually both exist at the same time.
What you are trying to do actually isn't that complicated. You just need to clean up your code:
Only define "private B bolt;" and its setters/getters once in your superclass.
Only use those getters/setters to access bolt
If you want your subclass to have a "bolt" of the type "BoltHexHead" then define the generic parameter as such in the class definition ("extends JointAttribute<BoltHexHead>" instead of "extends JointAttribute<Bolt<BoltSpec>>")
A simple example for demonstration purspose:
Superclass:
public class Superclass<T> {
private T value;
protected T getValue() {
return value;
}
protected void setValue(T value) {
this.value = value;
}
protected void print() {
if(getValue()==null) {
System.out.println("NULL");
} else {
System.out.println(getValue().toString());
}
}
}
Subclass1:
public class Subclass extends Superclass<String> {
public Subclass() {
}
public static void main(String[] args) {
Subclass subclass= new Subclass();
subclass.print();
subclass.setValue("test");
subclass.print();
}
}
Subclass2:
public class Subclass2 extends Superclass<Integer> {
public Subclass2() {
}
public static void main(String[] args) {
Subclass2 subclass= new Subclass2();
subclass.print();
subclass.setValue(3);
subclass.print();
}
}

how does base class know about sub class method?

public class BaseClass {
private String className;
public BaseClass() {
className = "[BaseClass]";
}
public void executeAB() {
System.out.println(className + " executingAB()");
executeA();
executeB();
}
public void executeA() {
System.out.println(this.className + " executingA()");
}
public void executeB() {
System.out.println(this.className + " executingB()");
}
}
public class SubClass extends BaseClass {
private String className;
public SubClass() {
this.className = "[SubClass]";
}
public void executeA() {
System.out.println(className + " executingA()");
}
public void executeC() {
System.out.println(className + " executingC()");
}
public static void main(String[] args) {
BaseClass t = new SubClass();
t.executeAB();
// t.executeC();
}
}
In above case , Calling t.executeAB() results in output:
[BaseClass] executingAB()
[SubClass] executingA()
[BaseClass] executingB()
My Question is:
How does BaseClass know about excuteA() method from SubClass, while at the same time t.executeC() call is not possible because BaseClass is not aware of executeC().
You have a misunderstanding of what you should be doing in inheritance. extends is a reserved word that was wisely chosen. The point of B extending A is to say that B is a subset of A with additional attributes. You're not supposed to redefine x in B; A should be handling x. You should have not className declared in both classes.
As for your example:
BaseClass t = new SubClass();
Calls the constructor for SubClass, which sets className of SubClass to [SubClass]. The super contructor is also called, and className in BaseClass is set to [BaseClass].
t.executeAB();
Prints the className for BaseClass which is [BaseClass] and then calls:
executeA();
executeB();
executeA() is a called from SubClass, since t is a SubClass and it's defined, so we get [SubClass] and finally, executeB() is called from BaseClass so again, we get [BaseClass]. As for why you can't call:
t.executeC()
Despite using the constructor for SubClass, t is a BaseClass. According to the principles of OOP, it makes sense that you can't call t.executeC(), since it is not defined for BaseClass.
You're defining your variable as BaseClass t = new SubClass(); which means you allow space for a different subclass to instantiate. However, in order for this to be possible without breaking existing code, you can only use methods that are defined in the baseclass.

OOP inheritance execution

Why does the execution of TestClass.main() outputs 202 202 101??
class BaseClass
{
int data = 101;
public void print()
{
System.out.print(data + " ");
}
public void fun()
{
print();
}
}
class SubClass extends BaseClass
{
int data = 202;
public void print()
{
System.out.print(data + " ");
}
}
class TestClass
{
public static void main(String[] args)
{
BaseClass obj = new SubClass();
obj.print();
obj.fun();
System.out.print(obj.data);
}
}
With my poor OOP knowledge I think the execution must be this way:
1- obj.print(); prints 202 from SubClass
2- Since there is no obj.fun(); method in Subclass it calls parent method so the output should be 101
3- System.out.print(obj.data); should print 202 since the value is overridden in subclass.
So I think the output would be 202 101 202 but it isn't, can you explain me why?
Since there is no obj.fun(); method in Subclass it calls parent method so the output should be 101
Indeed, it calls the super class for fun, but the super class calls print, and as print is overridden, the overriding version (in the subclass) gets called.
System.out.print(obj.data); should print 202 since the value is overwritten in subclass.
Variables are not overriden, but hidden by subclass, as obj declared as BaseClass, it accesses it data property directly. unlike method call, this is decided at compile time.
Because method are polymorphic and fields are not
if you remove
int data = 101;
from your BaseClass it will not compile
The trick is in deciding which method is executed. That choice is made from the type of the instance of the object. In your case, obj is a SubClass and every call to print() will execute the print method of SubClass. This mechanism is called Polymorphism in OOP.
Instead of mixing methods and variables, I'd recommend you start by just doing some testing on methods only. The code is mostly the same, with the same Polymorphism behavior, but without the variables.
class BaseClass
{
public void print()
{
System.out.print(101 + " ");
}
public void fun()
{
print();
}
}
class SubClass extends BaseClass
{
public void print()
{
System.out.print(202 + " ");
}
}
class TestClass
{
public static void main(String[] args)
{
BaseClass obj = new SubClass();
obj.print();
obj.fun();
}
}
1 and 2 - methods are polymorphic - method from base class will use method from sub class, if it will be able and ofc if you have reference to sub class
3 - field isnt polymorphic. It's taken from the type of reference.

What's the difference between this and super keywords in java?

Check my coolMethod, babes:
package zoo;
public class Zoo {
public String coolMethod() {
return "Wow baby!";
}
}
My Moo Class, that extends my Zoo class, full of ways to do the same thing, which is calling my coolMethod.
package zoo;
public class Moo extends Zoo {
public void useAZoo(){
Zoo z = new Zoo();
System.out.println("A Zoo says: "+ z.coolMethod());
}
public void useMyCoolMethod(){
System.out.println("My cool method says: " + super.coolMethod());
}
public void useMyCoolMethodAgain(){
System.out.println("My cool method says: " + this.coolMethod()+ " (again)");
}
public void inheritMyMethod(){
System.out.println("My inhertied method says: " + coolMethod());
}
}
And my main, that calls my Moo class functionalities.
package javacert1;
import zoo.Moo;
public class Main {
public static void main(String[] args) {
Moo moo = new Moo();
moo.useAZoo();
moo.useMyCoolMethod();
moo.useMyCoolMethodAgain();
moo.inheritMyMethod();
}
}
As you can see, all those four calls get the same results. I'm learning Java and I practiced with an example that used the "this" but I had seen the use of "super" elsewhere so I tested it and the results where the same. Why is this? What's the major difference between a this and super keyword?
Since you have only one coolMethod, it is called in each case, regardless of qualifiers. However, if you override your method in Moo e.g. like this
public class Moo extends Zoo {
public String coolMethod() {
return "Yeah dude!";
}
// the rest is the same as above...
}
you will notice the difference between the calls to coolMethod() and this.coolMethod() versus the call to super.coolMethod().
this can be pointing to current object
super can be used for accessing Super class metods & variables
this() can be used to invoke a constructor of the same class
super() can be used to invoke a super class constructor
Difference with examples
Cool example, overmann :)
Here is another example ... has 2 source files - LevelSub.java which extends LevelSup.java
Save the 2 in some folder, compile using "javac LevelSub.java" (compiler will know from "extends" that it has to compile "LevelSup.java", too), and run "java LevelSub". The comments in the source code should tell you the difference.
this and super are used when there is a name clash for variables or methods (e.g., same name is used in super/sub classes or in a method body, or you want to call a method from the superclass that has been overridden). "this" refers to the current object instance and "super" refers to the one it is inheriting from. For no name clashes, the this or super prefix are redundant.
public class LevelSub extends LevelSup {
protected String myName;
public LevelSub (String myName) {
super ("SuperClass");
this.myName = myName; // sets up instance variable
}
public void print () {
System.out.println ("Hi, this is " + myName); // refers to this.myName
System.out.println ("I am inherited from " + super.myName);
System.out.println ("also known as " + defaultName); // gets from superclass
super.print(); // overridden method of superclass
}
public static void main (String[] args) {
new LevelSub("SubClass").print();
}}
and the other source ...
public class LevelSup {
// cannot be private if accessed by subclass
protected String myName, defaultName = "TopLevel";
public LevelSup (String name) {
myName = name; // this not required, no name clash
}
// cannot be private if accessed by subclass
public void print () {
System.out.println ("Hi, this is " + myName);
}
}
You are not overriding the coolMethod and you are inheriting it.
As a result it calls the same method.
Override coolMethod and see what happens.
super will call the method of base.
this will call method in this object
"this" refers to the object you're in. "super" refers to the parent of this object. I think you're missing the difference because of some other things you have going on.
For example, this code
public class Zoo {
public String coolMethod() {
return "Wow baby!";
}
}
public class Moo extends Zoo {
public void useAZoo(){
Zoo z = new Zoo();
System.out.println("A Zoo says: "+ z.coolMethod());
}
public void useMyCoolMethod(){
System.out.println("My cool method says: " + super.coolMethod());
}
public void useMyCoolMethodAgain(){
System.out.println("My cool method says: " + this.coolMethod()+ " (again)");
}
public void inheritMyMethod(){
System.out.println("My inhertied method says: " + coolMethod());
}
}
The method "coolMethod" is defined in Zoo, but it's a public method so it is naturally inherited by Moo. So, when you're within your Moo class and you call this.coolMethod or super.coolMethod, you end up with exactly the same thing. Where things get far more interesting is if you override the coolMethod in your subclass, like this:
public class Zoo {
public String coolMethod() {
return "Wow baby!";
}
}
public class Moo extends Zoo {
#Override
public String coolMethod() {
return "Moo baby!";
}
public void doIt() {
System.out.println("Using super: " + super.coolMethod());
System.out.println("Using this: " + this.coolMethod());
}
}
Try executing "doIt" in that case and I think you'll see the difference much easier.
In this case, they will do nothing different.
However, if you were to override coolMethod in the Moo class, the call to the super version will call the version in the Zoo class, but all the other versions will call the new overridden one.
To see the difference, overwrite the coolMethod in your subclass Moo:
public String coolMethod() {
return "Moo baby!";
}
I suggest you, to create a coolMethod in your Moo class, that print something different, from the one in the Zoo class

Categories

Resources