Java abstract class constructor and new keyword - java

I am a junior developer and I am familiar with the theory behind java abstract classes and how they can have constructors to force subclasses to set certain constructor parameters, and how abstract classes themselves cannot be instantiated. However, when looking at some refactored code in my company's test framework I am slightly puzzled.
This abstract class
public abstract class WaitForTestOutcomeThenAssert {
private long maxWait;
public WaitForTestOutcomeThenAssert(long maxWait) {
this.maxWait = maxWait;
}
public void waitForConditionThenAssert() {
...
...
}
protected abstract boolean checkCondition();
}
gets referenced in this class:
public class DbWrapper extends AbstractDB {
#Override
public void assertColumnValueNotNull(final String schema, final String table, final String columnName, final String whereClause) {
new WaitForTestOutcomeThenAssert(this.assertionTemporalTolerance) {
#Override
public boolean checkCondition() {
return getColumnValue(schema, table, columnName, whereClause) != null;
}
}.waitForConditionThenAssert();
}
}
Since we can't instantiate an abstract class, can someone please explain to me exactly what happens and what gets created when we use new keyword in front of an abstract class constructor?

Try looking at anonymous classes. Here you have an anonymous class declaration that extends abstract class WaitForTestOutcomeThenAssert and overrides checkCondition method.

This is not an abstract class
new WaitForTestOutcomeThenAssert(this.assertionTemporalTolerance) {
#Override
public boolean checkCondition() {
return getColumnValue(schema, table, columnName, whereClause) != null;
}
}
That is an anonymous class that extends WaitForTestOutcomeThenAssert. In other words, by writing that you are subclassing "WaitForTestOutcomeThenAssert" and instantiating it.

This is an Anonymous class. It's a shortcut to use Abstract class or Interface without having to explicitly write a subclass.

Related

How define class and interface hierarchy?

I am confused about how to define classes and interfaces hierarchy for below scenario.
Below are the interfaces
public interface Save {
public void save(List<Object> pojoList);
public void save(String query);
}
public interface Update {
public void update(List<Object> pojoList, List<String> conditionList);
public void update(String query);
}
public interface Delete {
public void delete(String query);
}
And here are the classes :
Class DbOperations {
}
class SaveOperation extends DbOperations implements Save {
}
class UpdateOperation extends DbOperations implements Update {
}
So my concerns are:
I want call SaveOperation, DeleteOpration class methods using instance of DbOperations (base class)
can you tell me which class should be which interface?
any modification for above hierarchy??
Thanks in advance
What you get by having an interface implemented by multiple classes is that you can define a method that takes the interface as parameter and calls one of its methods, then the result of that call would depend on the actual type of that interface at runtime.
That said, I don't see any advantage in defining an interface DbOperation that doesn't define any method its classes will inherit.
If you have reasons to do so (it's possible, if the code you wrote is just a simplification of your scenario), from a semantical point of view I would find more meaningful having DbOperations as the root interface of the hierarchy, and Save, Update and Delete as abstract classes (or interfaces) between the actual classes and the root:
public interface DbOperation {
public String thisOperation();
}
public abstract class Save implements DbOperation {
public String thisOperation(){
return "Save";
}
public void save(List<Object> pojoList);
public void save(String query);
}
public abstract class Update implements DbOperation{
public String thisOperation(){
return "Update";
}
public void update(List<Object> pojoList, List<String> conditionList);
public void update(String query);
}
public abstract class Delete implements DbOperation {
public String thisOperation(){
return "Delete";
}
public void delete(String query);
}
class SaveOperation implements Save {
}
class UpdateOperation implements Update {
}
So regarding your concern,
I want call SaveOperation, DeleteOpration class methods using instance
of DbOperations (base class)
I think, it will go something like this:
DbOperations op = new SaveOperation(/*Params*/);
// Check type to cast
if(op instanceof Save)
{
// Cast to Save and call method
((Save)op).save(/*Params*/);
}
// For delete
if(op instanceof Delete)
{
// Cast to Save and call method
((Delete)op).delete(/*Params*/);
}
So, you don't need any modification.

Java Returning Type of Child class (abstract)

I've been trying my best with some basic code, and I am completely stuck...
I have an abstract class "Piece":
public abstract class Piece {
private static int type;
public int getType() {
return type;
}
}
The "Pawn" is the Child:
public class Pawn extends Piece {
private static final int type = 1;
}
And now for the problem: When creating the Pawn with Pawn p = new Pawn();, p.getType() returns 0, not 1...
How can I fix this?
The problem is that you already have a variable declared in your abstract class. You shouldn't redeclare it in your subclass. Instead, set the abstract class's variable like this:
public class Pawn extends Piece {
public Pawn() {
type = 1;
}
}
You should also declare the variable as protected so that subclasses can access it and refrain from making it static, since that will allow only one value for all subclasses:
public abstract class Piece {
protected int type;
public int getType() {
return type;
}
}
This code you write relies on an instance and not on a static context:
Pawn p = new Pawn();
p.getType();
A static final field is not designed to be inherited by child classes.
And creating a static final field in the child class with the same name as in the parent class doesn't allow to override it either.
1) So you should use an instance field and not a static field for the type field.
2) If you want to override the behavior of getType() in the child class, in fact you don't even need to use a field. Using a method should be enough.
In the base class :
public abstract class Piece {
public int getType() {
return 0;
}
}
In the child class :
public class Pawn extends Piece {
#Override
public int getType() {
return 1;
}
}
Here is one way. But you really need to read up on classes and abstract classes.
public abstract class Piece {
public int getType() {
return 0;
}
}
public class Pawn extends Piece {
public int getType() {
return 1;
}
}
Having a static variable in a class means that all instances of that class share the same value. I don't think that's what you intended.
Also, you can use the hierarchy of inheritance to your advantage by not redefining the getType() method.
Here is one of many ways to solve it:
public abstract class Piece {
protected int type;
public int getType() {
return type;
}
}
public class Pawn extends Piece {
public Pawn() {
type = 1;
}
}
There are two problems with your approach.
The first is that Java does not support inheritance of static methods. Not that it couldn't have supported this - it's just a design choice. What this means is that any method of class Piece, which calls getType() - calls the Piece class' implementation of getType(), not a polymorphic call to getType() of whatever the actual subclass is.
The second problem is that you're sort of reinventing the wheel. Java has rich reflection facilities: You can use getClass() and instanceof for your check:
if(myObject instanceof Piece && myObject.getClass() != Piece.class) {
// do stuff
}
and of course you can make this a method of the piece class (no need to override it).

How To Access Sub Class Variable From Generic Super Class

I am trying to create a generic method, but it requires data from the sub class. Is there a way to do this, or is there a better implementation?
Example of my situation:
public class Super {
public static Object method() {
return doSomethingWith(specificToSubClassValue);
}
}
public class Sub1 extends Super {
public static String specificToSubClassValue = "123";
}
public class Sub2 extends Super {
public static String specificToSubClassValue = "456";
}
I obviously cannot do this. What is a better approach?
One alternative I can think of is to override the #method method in each sub class, but it will be the same code in each instance so I wanted to throw it in the parent class (and it won't be truly overridden since it is static), but I am not sure how to approach it since it is dependent on the sub class value.
Static methods in Java can't be overwritten, and can't access children-specific information: they know nothing about inheritance.
What you need here is instance method, which you can overwrite. An you also may use generics.
public class Super<T> {
public Object method() {
final T specificToSubClassValue = getSpecificToSubClassValue();
if (specificToSubClassValue != null) {
return specificToSubClassValue.hashCode();
} else {
return null;
}
}
protected T getSpecificToSubClassValue() {
return null;
}
}
class Sub1 extends Super<String> {
#Override
protected String getSpecificToSubClassValue() {
return "abc";
}
}
class Sub2 extends Super<Integer> {
#Override
protected Integer getSpecificToSubClassValue() {
return 123;
}
}
Declare an abstract method in Super, which will be used to return the value from the implementing classes. Note that this can only be achieved with non-static methods. As per #JB Nizet's comment, static methods cannot be overriden by subclasses. I've removed the static modifier from the code below to shown you how it would work.
public class Super {
public static Object method() {
return doSomethingWith(specificToSubClassValue);
}
protected abstract Object getValue ();
}
public class Sub1 extends Super {
public static String specificToSubClassValue = "123";
#Override
protected Object getValue () {
return specificToSubClassValue;
}
}
public class Sub2 extends Super {
public static String specificToSubClassValue = "456";
#Override
protected Object getValue () {
return specificToSubClassValue;
}
}
Well, te whole idea of inheritance is that the superclass should not be able to do that much without the sub-class. Otherwise the whole inheritance would be pointless exercise and spaghetti code. But you are tackling the problem the wrong way. Make sub-class "spill" the data you need (through getter) and use the generic method from superclass on the data in the sub-class.
Also the overriding of super class methods is highly overrated. You should strive for your super method to be as flexible and re-usable as possible, and even then strive rather for overloading, instead of overriding.
You could have:
public class Super {
public Object method(String specificValue) {
return doSomethingWith(specificToSubClassValue);
}
And then have your sub do this
public class Sub1 extends Super {
public static String specificToSubClassValue = "123";
Object method(specificToSubClassValue);
}
This way you accomplish exactly what you want, operate on the class specific value using the super 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";
}
}

Java access to generic parameter of outer class from inner interface

Consider the code:
public class A<T extends X> {
public static interface Delegate {
void doMagic(T t); // why can't I access "T" here?
}
public A(Delegate delegate) { ... }
}
...
public class TheDelegate implements A<Y> { ... }
...
A<Y> a = new A<Y>(new A<Y>.Delegate() {
#Override
public void doMagic(Y y) {
...
}
});
Why can't I access T from Delegate interface?
It's because your inner interface is static. The generic parameter only applies to an instance of A as opposed to applying to the class, so the scope of T is the non-static scope of A.
In case you didn't know, all interfaces and enumerations are static in Java, even if they are not declared as static and are inside another class. Therefore there is no way to work around this with an interface.
See this answer also.
EDIT: Steven's answer is correct. However, your user code will look like this:
// Note the extra declaration of the generic type on the Delegate.
A<Integer> a = new A<Integer>(new A.Delegate<Integer>() {
#Override
public Integer myMethod() {
return null;
}
});
Your inner interface can have its own generic bounds. Try declaring and using it as Delegate<T> and it should work fine.

Categories