Use subclass member variable in super class methods? - java

I have a base class and subclass. Base class has common methods and its implementation which I want to use in subclass but I want to use subclass member variable instead of superclass. I do not want to rewrite the same method in subclass. Is there a way in Java to achieve this.

You could create a protected setter on the member variable & then override the value of the super's variable within the constructor of the subclass:
class Animal {
private String voice = "Oooo";
protected void setVoice(String voice) {
this.voice = voice;
}
public void speak() {
System.out.println(this.voice);
}
}
class Dog extends Animal {
public Dog() {
setVoice("woof");
}
}

You can use a method to access the member and override it in subclasses.
Class A{
public void DoStuff(){
int aux = getResource;
/*cool things with aux*/
}
protected int getResource(){
return internal_member;
}
private int internal_member;
}
Class B extends A{
private int another_member;
#Override
public int getResource(){
return another_member;
}
}
But take into account that this will not prevent people chaging class A from using the member directly, It might be better to create a base class for the members and the getters.
Another Option, as some people outlined before is to have the data member in the base class as protected and initialize it in the subclass:
Class A{
public void DoStuff(){
/*cool things with internal_member*/
}
protected List internal_member;
A(){internal_member = /*Set here a value*/}
}
Class B extends A{
B(){internal_member = /*Set a different value here! you can even declare a member and assign it here*/}
}
You can use constructors with arguments if you need.

Related

Checkstyle error for protected variable in abstract classes

I'm kind of new to java and I'm facing an issue with protected variable in an abstract class. I've added the implementation below:
Abstract class:
public abstract class blah1 implements blah {
protected variable1
//// stuff///
}
sub class:
public class blah2 extends blah1 {
///uses variable1///
}
Checkstyle says I should convert the variable to private and then use get/set methods. But how do I accomplish this within an abstract-class/sub-class situation?
Make variable private in parent class, then add getter and setter
public abstract class blah1 {
private int variable;
public int getVariable() {
return variable;
}
public void setVariable(int variable) {
this.variable = variable;
}
//// stuff///
}
How to use it in the child class. Note the super keyword
public class blah2 extends blah1 {
void useVariable() {
super.getVariable(); // get variable
super.setVariable(1); // set variable
}
}
EDIT
As stated by #Pshemo it's legit removing the super keyword (and you should do it if you're planning to override the getter and setter in order to use the overriden version) obtaining:
void useVariable() {
getVariable(); // get variable
setVariable(1); // set variable
}
Anyway the version using super lets you understand how you can call the original version of those methods

Can a variable be abstract in an abstract Java class?

Can you declare an abstract variable type in an abstract class? I am receiving an error when I put this line of code in. I can declare a variable that is final and not final but I am not sure if I should be able to declare a variable that is abstract. What would be the real advantage between an interface and an abstract class?
Error Code:
abstract int myScore = 100; <-- Causes an error
Code:
public abstract class GraphicObject {
int home = 100;
String myString = "";
final int score = 0;
abstract void draw();
abstract void meMethod1();
abstract void meMethod2();
int meMethod3() {
return 0;
}
}
"Can you declare an abstract variable type in an abstract class?"
No, according to the JLS (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1).
Why should it be abstract if you can't implement variables?
Abstract methods only mean that they must be implemented further in your code (by a class that extends that abstract class).
For variable that won't make any since they keep being the same type. myscore will always be an int.
You may be tinking about override the value of myscore by the class that extends that abstract class.
An abstract method is a method that doesn't have a body. This is because it's meant to be overridden in all concrete (non-abstract) subclasses and, thanks to polymorphism, the abstract stub can never be invoked.
Given the above, and since there is no polymorphism for fields (or a way to override fields at all), an abstract field would be meaningless.
If what you want to do is have a field whose default value is different for every subclass, then you can assign its default value in the constructor(s) of each class. You don't need to make it abstract in order to do this.
No, abstract is used so that methods can only be implemented in subclasses. See http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
You cannot declare an abstract variable in Java.
If you wish to declare a variable in a super-class, which must be set by its sub-classes, you can define an abstract method to set that value...
For example:
public abstract class Foo {
Object obj;
public Foo() {
init();
}
protected void init() {
obj = getObjInitVal();
}
abstract protected Object getObjInitVal();
}
public class Bar extends Foo {
#Override
protected Object getObjInitVal() {
return new Object();
}
}
Base on "AlonL" reply :
You can do this too
public abstract class Foo {
Object obj;
public Foo() {
init();
}
abstract protected void init();
}
public class Bar extends Foo {
#Override
protected void init() {
obj = new Object();
}
}

How to define constants/final variables in abstract superclasses but assign them in the subclass?

I have a abstract class where I want to declare final variables.
However, I want to assign the values to these variables only in the constructors of my sub-classes.
Apparently, this is not possible because all "final fields have to be initialized". I do not see why, since it is not possible anyway to instantiate an abstract class.
What I would like to have is something like this:
abstract class BaseClass {
protected final int a;
}
class SubClass extends BaseClass {
public SubClass() {
a = 6;
}
}
I imagine something similar to methods when you implement an interface. Then you are also forced to to implement the methods in the (sub-)class.
You should define a constructor in your abstract class that takes a value for a and call this constructor from your sub classes. This way, you would ensure that your final attribute is always initialized.
abstract class BaseClass {
protected final int a;
protected BaseClass(int a)
{
this.a = a;
}
}
class SubClass extends BaseClass {
public SubClass() {
super(6);
}
}

Overriding Protected Methods

I'm new to Java and I have a very basic question.
I have 2 Parent Class under the same package. Animal Abstract Class and the Machine Class.
Now, the Animal Abstract Class has a protected method. I'm aware that protected methods are accessible if the classes are under the same package.
I can access that protected method in my Machine Class, and the question is.. Is it possible to override that protected method? Without extending the Animal Class.
protected - Can be overridden by subclasses, whether they are in the same package or not
default (no access modifier) - can only be accessed or overridden if both the classes are in the same package
You can only override methods through extension.
You can override a protected method with an anonymous subclass, if you like. E.g.
public class Animal {
protected String getSound() {
return "(Silence)";
}
public void speak() {
System.out.println(getSound());
}
}
In another class:
public static void main(String ... args) {
Animal dog = new Animal() {
#Override
protected String getSound() {
return "Woof!";
}
}
dog.speak();
}
Will output:
Woof!
No , Overriding means inherit the behavior from parent class and that is not possible without extending the class.
public class PClass
{
protected boolean methodA()
{
return true;
}
}
public class CClass extends PClass
{
protected boolean methodA()
{
return false;
}
}
Run the code below to test it
public static void main(String[] args)
{
PClass pc = new CClass();
System.out.println(pc.methodA());
}
O/p=false
here we are overriding the behavior of methodA
In order to override a method you have to extend that class. That's what overriding means: having a method with the same signature as the super-class.
Overriding by definition says..
An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.
So AFAIK if you don't extend the super class there is no way to override the method.

Super class which uses the values from children

I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}

Categories