class Base {
Base() {
System.out.println("Base Constructor");
}
}
class Derived1 extends Base {
private static String pattern = "a+b+";
Derived1() {
super();
System.out.println("Derived 1 Constructor");
}
public static boolean doesMatch(String v) {
return v.matches(pattern);
}
}
class Derived2 extends Base {
private static String pattern = "c+";
Derived2() {
super();
System.out.println("Derived 2 Constructor");
}
public static boolean doesMatch(String v) {
return v.matches(pattern);
}
}
class Builder {
public static Base baseFromString(String v) throws Exception {
if (Derived1.doesMatch(v)) return new Derived1();
if (Derived2.doesMatch(v)) return new Derived2();
throw new Exception("Could not match " + v + " to any derived type.");
}
}
class Test {
public static void main(String[] args) throws Exception {
Base b = Builder.baseFromString("aaab");
}
}
The code above has a primary problem I want to solve:
The doesMatch method is repeated code for the two derived classes. I'd like to move it to the base class, but then it won't be able to access the pattern member. How do I structure my code better so that each derived class can have its own static pattern, while they all share the same base doesMatch method?
I've tried messing around with abstract classes and interfaces, but I couldn't get anything to work. I am fine with those types of solutions as long as there is a hierarchy where the derived classes either extend or implement the base class.
Secondary question (from original post)
I might want to add several more derived classes. I'd like to not have to update the baseFromString method with another if every time I extend the base class. Is this something that can be solved with polymorphism?
A functional technique (Java 9+), but there is some performance overhead:
class Base {
Base() {
System.out.println("Base Constructor");
}
}
class Derived1 extends Base {
Derived1() {
super();
System.out.println("Derived 1 Constructor");
}
}
class Derived2 extends Base {
Derived2() {
super();
System.out.println("Derived 2 Constructor");
}
}
interface NewBase {
Base create();
}
final class Pattern {
final private String pattern;
final private NewBase newBase;
public Pattern(String pattern, NewBase newBase) {
this.pattern = pattern;
this.newBase = newBase;
}
public String getPattern() {
return pattern;
}
public NewBase getNewBase() {
return newBase;
}
}
class Builder {
final private static List<Pattern> newObjects = new ArrayList<>();
private static void addPattern(String pattern, NewBase newObject) {
newObjects.add(new Pattern(pattern, newObject));
}
static {
addPattern("a+b+", Derived1::new);
addPattern("c+", Derived2::new);
}
public static Base baseFromString(String v) throws Exception {
for (Pattern p : newObjects) {
if (v.matches(p.getPattern()))
return p.getNewBase().create();
}
throw new Exception("Could not match " + v + " to any derived type.");
}
}
Just update the static Builder initializer to call the addPattern for new patterns and derived classes.
You can't do that, at least not with static members. The problem is that static members cannot be overridden.
public class Driver {
public static void main(String args[]) {
Derived aDerived = new Derived();
aDerived.print(); // prints "Value is 5", not "Value is 10"
}
}
public class Base {
protected static final int VALUE = 5;
public Base() {}
protected void print() {
System.out.println("Value is " + VALUE);
}
}
public class Derived extends Base {
protected static final int VALUE = 10; // does not override base Value
public Derived() {}
}
Each subclass can have its own value, and they would all inherit print(). But it doesn't do what you want because print() will always reference Base.VALUE even in the inherited Derived.print().
So, static doesn't work. I assume that you feel the pattern member needs to be static because there only needs to be one copy of the pattern value for the entire class. That one copy part should have tipped you off to a handy little design pattern: the singleton pattern!
public class Driver {
public static void main(String args[]) {
Derived aDerived = new Derived();
aDerived.print(); // prints "Value is 10"
}
}
public class Base {
protected Value val = Value.getInstance();
public Base() {}
protected void print() {
System.out.println("Value is " + val.value());
}
}
public class Derived extends Base {
public Derived() { val = DerivedValue.getInstance(); }
}
public class Value {
private int value = 5;
public int value() { return value; }
private static Value instance = new Value();
protected Value() {}
public static Value getInstance() { return instance; }
}
public class DerivedValue extends Value {
private int value = 10;
public int value() { return value; }
private static DerivedValue instance = new DerivedValue();
private DerivedValue() {}
public static DerivedValue getInstance() { return instance; }
}
There's a lot more code in this version, but now there is only one copy of the two different values used.
Note: Below is how you can make the value members final. You'll have to set up your packages appropriately so the protected Base(Value v) constructor is only visible to the Derived class.
public class Base {
protected final Value val;
public Base() { val = Value.getInstance(); }
protected Base(Value v) { val = v; }
protected void print() {
System.out.println("Value is " + val.value());
}
}
public class Derived extends Base {
public Derived() { super(DerivedValue.getInstance()); }
}
I want to access and use 3 private variables in an Abstract Class(MainAbstract.java) from another class that has extended (SubAbstract.java) from the previously mentioned Abstract Class.
From the sub class I want to access the getters() and setters() of the main class's.
In the main class (this is an abstract class) there is an abstract method called ShowInfo().
This ShowInfo() abstract method should do something to view the each instance of the subclass's.
Below is the source code for the MainClass(Abstract) and the Sub Class SubAbstract. Please refer them.
MainAbstract.java
package abstractionexample;
public abstract class MainAbstract {
private String sName;
private String sType;
private int iQty;
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public String getsType() {
return sType;
}
public void setsType(String sType) {
this.sType = sType;
}
public int getiQty() {
return iQty;
}
public void setiQty(int iQty) {
this.iQty = iQty;
}
public abstract void showInfo();
public static void main(String[] args) {
}
}
SubAbstract.java
package abstractionexample;
public class SubAbstract extends MainAbstract{
#Override
public void showInfo() {
}
//This is an instance and the getters() and setters() should use each instance of this kind of to get values and set values.
SubAbstract nSubAbs = new SubAbstract();
}
If I understand correctly, you want to use the setter methods to set properties of the instance nSubAbs and show these properties using the showInfo() method.
The getters and setters are readily available to you in your subclass SubAbstract because it has inherited from the parent class MainAbstract
Here's a code sample:
class SubAbstract extends MainAbstract{
SubAbstract nSubAbs;
SubAbstract(int iQty, String name, String type) {
nSubAbs = new SubAbstract();
this.nSubAbs.setiQty(iQty);
this.nSubAbs.setsName(name);
this.nSubAbs.setsType(type);
}
private SubAbstract() {
//no arg constructor
}
#Override
public void showInfo() {
System.out.println("iQty:" + nSubAbs.getiQty());
System.out.println("name:" + nSubAbs.getsName());
System.out.println("type:" + nSubAbs.getsType());
}
}
And the main method of your MainAbstract class would look something like this (although this is a very bad place for the main method, but I suppose, you are trying to experiment)
public abstract class MainAbstract {
//..existing code..
public static void main(String[] args) {
SubAbstract subAbstract = new SubAbstract(10, "someName", "someType");
subAbstract.showInfo();
}
}
In this class abstract class object is instantiated by overriding the getNum(), what is the purpose of this?
public abstract class AbstractTest {
public int getNum() {
return 45;
}
public static void main(String[] args) // main function
{
AbstractTest t = new AbstractTest() // From this point didn't understand
{
public int getNum() // function
{
return 22;
}
}; //use of this
System.out.println(t.getNum()); // output
}
}
The instantiation in your main() method is simply an inline class definition of a concrete instance of the abstract class AbstractTest. To be clear, the variable t is an anonymous, non abstract class instance. The following code would achieve the same thing:
public class ConcreteTest extends AbstractTest {
#Override
public int getNum() {
return 22;
}
}
public static void main (String [] args) {
ConcreteTest t = new ConcreteTest();
System.out.println(t.getNum());
}
There are instances in the course of development where it can be cumbersome to have to create a formal class definition. For example, if you only need a single instance of the abstract AbstractTest class, it would be easier to use an inline definition.
We call this 'Anonymous Class': When you need to create and use a class, but do not need to give its name or reused use, you can use an anonymous class. Here is the offical doc. Not only used for abstract class, can also be used for interface and general extensible class.
interface Base {
void print();
}
public static void main(String[] args) {
Base aInterface = new Base() {
#Override
public void print() {
System.out.println("A anonymous implement.");
}
};
Thread aThread = new Thread() {
#Override
public void run() {
super.run();
}
};
}
public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??
You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members
Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass
Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.
I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}
Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
}
public void doIt()
{
new Son().printMe();
}
The function doIt will print "dad". Is there a way to make it print "son"?
In short, no, there is no way to override a class variable.
You do not override class variables in Java you hide them. Overriding is for instance methods. Hiding is different from overriding.
In the example you've given, by declaring the class variable with the name 'me' in class Son you hide the class variable it would have inherited from its superclass Dad with the same name 'me'. Hiding a variable in this way does not affect the value of the class variable 'me' in the superclass Dad.
For the second part of your question, of how to make it print "son", I'd set the value via the constructor. Although the code below departs from your original question quite a lot, I would write it something like this;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void printName() {
System.out.println(name);
}
}
The JLS gives a lot more detail on hiding in section 8.3 - Field Declarations
Yes. But as the variable is concerned it is overwrite (Giving new value to variable. Giving new definition to the function is Override). Just don't declare the variable but initialize (change) in the constructor or static block.
The value will get reflected when using in the blocks of parent class
if the variable is static then change the value during initialization itself with static block,
class Son extends Dad {
static {
me = "son";
}
}
or else change in constructor.
You can also change the value later in any blocks. It will get reflected in super class
Yes, just override the printMe() method:
class Son extends Dad {
public static final String me = "son";
#Override
public void printMe() {
System.out.println(me);
}
}
You can create a getter and then override that getter. It's particularly useful if the variable you are overriding is a sub-class of itself. Imagine your super class has an Object member but in your sub-class this is now more defined to be an Integer.
class Dad
{
private static final String me = "dad";
protected String getMe() {
return me;
}
public void printMe()
{
System.out.println(getMe());
}
}
class Son extends Dad
{
private static final String me = "son";
#Override
protected String getMe() {
return me;
}
}
public void doIt()
{
new Son().printMe(); //Prints "son"
}
If you are going to override it I don't see a valid reason to keep this static. I would suggest the use of abstraction (see example code). :
public interface Person {
public abstract String getName();
//this will be different for each person, so no need to make it concrete
public abstract void setName(String name);
}
Now we can add the Dad:
public class Dad implements Person {
private String name;
public Dad(String name) {
setName(name);
}
#Override
public final String getName() {
return name;
}
#Override
public final void setName(String name) {
this.name = name;
}
}
the son:
public class Son implements Person {
private String name;
public Son(String name) {
setName(name);
}
#Override
public final String getName() {
return name;
}
#Override
public final void setName(String name) {
this.name = name;
}
}
and Dad met a nice lady:
public class StepMom implements Person {
private String name;
public StepMom(String name) {
setName(name);
}
#Override
public final String getName() {
return name;
}
#Override
public final void setName(String name) {
this.name = name;
}
}
Looks like we have a family, lets tell the world their names:
public class ConsoleGUI {
public static void main(String[] args) {
List<Person> family = new ArrayList<Person>();
family.add(new Son("Tommy"));
family.add(new StepMom("Nancy"));
family.add(new Dad("Dad"));
for (Person person : family) {
//using the getName vs printName lets the caller, in this case the
//ConsoleGUI determine versus being forced to output through the console.
System.out.print(person.getName() + " ");
System.err.print(person.getName() + " ");
JOptionPane.showMessageDialog(null, person.getName());
}
}
}
System.out Output : Tommy Nancy Dad
System.err is the same as above(just has red font)
JOption Output: Tommy then Nancy then Dad
This looks like a design flaw.
Remove the static keyword and set the variable for example in the constructor. This way Son just sets the variable to a different value in his constructor.
Though it is true that class variables may only be hidden in subclasses, and not overridden, it is still possible to do what you want without overriding printMe () in subclasses, and reflection is your friend. In the code below I omit exception handling for clarity. Please note that declaring me as protected does not seem to have much sense in this context, as it is going to be hidden in subclasses...
class Dad
{
static String me = "dad";
public void printMe ()
{
java.lang.reflect.Field field = this.getClass ().getDeclaredField ("me");
System.out.println (field.get (null));
}
}
https://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html
It's called Hiding Fields
From the link above
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super, which is covered in the next section. Generally speaking, we don't recommend hiding fields as it makes code difficult to read.
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String _me = me = "son";
}
public void doIt()
{
new Son().printMe();
}
... will print "son".
It indeed prints 'dad', since the field is not overridden but hidden. There are three approaches to make it print 'son':
Approach 1: override printMe
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
#override
public void printMe()
{
System.out.println(me);
}
}
public void doIt()
{
new Son().printMe();
}
Approach 2: don't hide the field and initialize it in the constructor
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
public Son()
{
me = "son";
}
}
public void doIt()
{
new Son().printMe();
}
Approach 3: use the static value to initialize a field in the constructor
class Dad
{
private static String meInit = "Dad";
protected String me;
public Dad()
{
me = meInit;
}
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
private static String meInit = "son";
public Son()
{
me = meInit;
}
}
public void doIt()
{
new Son().printMe();
}
Variables don't take part in overrinding. Only methods do. A method call is resolved at runtime, that is, the decision to call a method is taken at runtime, but the variables are decided at compile time only. Hence that variable is called whose reference is used for calling and not of the runtime object.
Take a look at following snippet:
package com.demo;
class Bike {
int max_speed = 90;
public void disp_speed() {
System.out.println("Inside bike");
}
}
public class Honda_bikes extends Bike {
int max_speed = 150;
public void disp_speed() {
System.out.println("Inside Honda");
}
public static void main(String[] args) {
Honda_bikes obj1 = new Honda_bikes();
Bike obj2 = new Honda_bikes();
Bike obj3 = new Bike();
obj1.disp_speed();
obj2.disp_speed();
obj3.disp_speed();
System.out.println("Max_Speed = " + obj1.max_speed);
System.out.println("Max_Speed = " + obj2.max_speed);
System.out.println("Max_Speed = " + obj3.max_speed);
}
}
When you run the code, console will show:
Inside Honda
Inside Honda
Inside bike
Max_Speed = 150
Max_Speed = 90
Max_Speed = 90
only by overriding printMe():
class Son extends Dad
{
public void printMe()
{
System.out.println("son");
}
}
the reference to me in the Dad.printMe method implicitly points to the static field Dad.me, so one way or another you're changing what printMe does in Son...
You cannot override variables in a class. You can override only methods. You should keep the variables private otherwise you can get a lot of problems.
No. Class variables(Also applicable to instance variables) don't exhibit overriding feature in Java as class variables are invoked on the basis of the type of calling object. Added one more class(Human) in the hierarchy to make it more clear. So now we have
Son extends Dad extends Human
In the below code, we try to iterate over an array of Human, Dad and Son objects, but it prints Human Class’s values in all cases as the type of calling object was Human.
class Human
{
static String me = "human";
public void printMe()
{
System.out.println(me);
}
}
class Dad extends Human
{
static String me = "dad";
}
class Son extends Dad
{
static String me = "son";
}
public class ClassVariables {
public static void main(String[] abc) {
Human[] humans = new Human[3];
humans[0] = new Human();
humans[1] = new Dad();
humans[2] = new Son();
for(Human human: humans) {
System.out.println(human.me); // prints human for all objects
}
}
}
Will print
human
human
human
So no overriding of Class variables.
If we want to access the class variable of actual object from a reference variable of its parent class, we need to explicitly tell this to compiler by casting parent reference (Human object) to its type.
System.out.println(((Dad)humans[1]).me); // prints dad
System.out.println(((Son)humans[2]).me); // prints son
Will print
dad
son
On how part of this question:- As already suggested override the printMe() method in Son class, then on calling
Son().printMe();
Dad's Class variable "me" will be hidden because the nearest declaration(from Son class printme() method) of the "me"(in Son class) will get the precedence.
Just Call super.variable in sub class constructor
public abstract class Beverage {
int cost;
int getCost() {
return cost;
}
}`
public class Coffee extends Beverage {
int cost = 10;
Coffee(){
super.cost = cost;
}
}`
public class Driver {
public static void main(String[] args) {
Beverage coffee = new Coffee();
System.out.println(coffee.getCost());
}
}
Output is 10.
Of course using private attributes, and getters and setters would be the recommended thing to do, but I tested the following, and it works... See the comment in the code
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
/*
Adding Method printMe() to this class, outputs son
even though Attribute me from class Dad can apparently not be overridden
*/
public void printMe()
{
System.out.println(me);
}
}
class Tester
{
public static void main(String[] arg)
{
new Son().printMe();
}
}
Sooo ... did I just redefine the rules of inheritance or did I put Oracle into a tricky situation ?
To me, protected static String me is clearly overridden, as you can see when you execute this program. Also, it does not make any sense to me why attributes should not be overridable.
Why would you want to override variables when you could easily reassign them in the subClasses.
I follow this pattern to work around the language design. Assume a case where you have a weighty service class in your framework which needs be used in different flavours in multiple derived applications.In that case , the best way to configure the super class logic is by reassigning its 'defining' variables.
public interface ExtensibleService{
void init();
}
public class WeightyLogicService implements ExtensibleService{
private String directoryPath="c:\hello";
public void doLogic(){
//never forget to call init() before invocation or build safeguards
init();
//some logic goes here
}
public void init(){}
}
public class WeightyLogicService_myAdaptation extends WeightyLogicService {
#Override
public void init(){
directoryPath="c:\my_hello";
}
}