Extending an abstract constructor? - java

So I've come across a bit of a snag in some code that I'm working with. Essentially I have the following three tidbits of code:
Abstract class:
public abstract class TestParent {
int size;
public TestParent(int i){
size = i;
}
}
Child Class:
public class TestChild extends TestParent{
public void mult(){
System.out.println(this.size * 5);
}
}
Implementation:
public class TestTest {
public static void main(String args[]) {
TestChild Test = new TestChild(2);
Test.mult();
}
}

Consider the following case of abstract class and extends implementation.
https://stackoverflow.com/a/260755/1071979
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return muliplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a default constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.
NOTE: As there is no default (or no-arg) constructor in the parent abstract class the constructor used in subclasses must be specified.
Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.

public class TestChild extends TestParent{
public TestChild(int i){
super(i); // Call to the parent's constructor.
}
public void mult(){
System.out.println(super.size * 5);
}
}

Use super to call parent (TestParent.TestParent(int)) constructor:
public class TestChild extends TestParent{
public TestChild(int i) {
super(i);
}
//...
}
or if you want to use some constant:
public TestChild() {
super(42);
}
Note that there is no such thing as abstract constructor in Java. Essentially there is only one constructor in TestParent which must be called before calling TestChild constructor.
Also note that super() must always be the first statement.

When you have explicit constructor defined in super class and no constructor without arguments defined, your child class should explicitly call the super class constructor.
public class TestChild extends TestParent{
TestChild ()
{
super(5);
}
}
or, if you don't want call super class constructor with parameters, you need to add constructor with no arguments in super class.
public abstract class TestParent {
int size;
public TestParent(){
}
public TestParent(int i){
size = i;
}
}

You code wont compile because your base class does not have a default constructor. Either you need to provide it in base class or you need to provide parameterized constructor in derived class and invoke super.

public class TestChild extends TestParent{
public TestChild (int i)
{
super(i * 2);
}
}
This code would use the double of i. This is an overriding, though i'm not sure what you want to ask.
Other solution:
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i);
this.size = 105;
}
}
For this solution, size must be protected or public.

Related

Do i need to implement all the methods of interface again while inheriting abstract class in Java?

I am trying to extends an abstract class which is implemented one method of interface so in my subclass i am trying to implement rest of the methods declared in interface but sub class forcing me to declare all the methods of interface, please help me to fix this, thanks in advance i have added my code below. Thanks much in advance seniors.
My code
interface xxx
{
int numbers();
String names();
Double salary();
}
abstract class GetNames implements xxx
{
public String names()
{
return "Ravi";
}
}
class Check extends GetNames
//This class forcing me to implement names also
{
public int numbers()
{
return 3;
}
public double sal()
{
return 25000.00;
}
}
public class AbsUsingInterface {
}
You only need to implement methods from Interface which have not been implemented in abstract class which is a super class for your class where you are trying to implement methods.
But looks like I see one problem in your Check class.
Your interface declares this method,
Double salary();
Where as in check class you are implementing this method,
public double sal()
So this really doesn't implement a method from interface. You need to make it same as it is in interface.
Just make method in your Check class like this,
public Double salary()
{
return 25000.00;
}
While implementing/overriding a method from superclass/interface, you should always use #Override annotation so in case any of your method signature differs, it will prompt you for error right there. And yes if you declare names() method again in your subclass Check, it will override the one in abstract class.You can do something like this in your class,
abstract class GetNames implements xxx
{
#Override
public String names()
{
return "Ravi";
}
}
class Check extends GetNames
{
#Override
public int numbers()
{
return 3;
}
public double sal()
{
return 25000.00;
}
#Override
public Double salary() {
return sal();
}
#Override
public String names() { // this overrides names() method in GetNames class
return "Check";
}
}
A concrete class extending an abstract class must provide body to all the abstract method in super class.
Methods in an interface are by default- abstract unless you provide a default body.
When an abstract class implements an interface, all those methods of an interface are inherited as it is i.e. abstract
Now for your scenario, where you have provided a body for one of the inherited method of the interface, this method is no longer abstract in the scope of 'Abstract' class. So, if a class extends this abstract class, then it need not provide a body for the above method because it is no longer abstract(They can of-course override it).
You are getting an error in Check subclass that you have defined for not inheriting salary() method, not names() method that you have already defined in GetNames abstract class
your GetNames class is implementing xxx interface but you are only implementing names()
you must implement salary method.
interface xxx
{
int numbers();
String names();
Double salary();
}
abstract class GetNames implements xxx
{
public String names()
{
return "Ravi";
}
public Double salary()
{
return null;//just return null;
}
}
class Check extends GetNames
{
public int numbers()
{
return 3;
}
public double sal()
{
return 25000.00;
}
}
or just throw NotImplementedException;

Sub-class casting for methods

OK, so I'll start this with an example:
Let's say we have an abstract class with an interface variable, which is initialized in the constructor. The abstract class itself has a getter for that variable, it's subclasses have implementations of the interface in the constructor.
Now, the problem I'm getting is that when trying to call the getter of any of the subclasses (which is only declared in the superclass, but it should use the variable declared in their constructors) it doesn't return the implementation, it returns the interface itself.
public abstract class AbstractClass {
private final ExampleInterface exampleInterface;
public AbstractClass(ExampleInterface exampleInterface) {
this.exampleInterface = exampleInterface;
}
public ExampleInterface getExampleInterface() {
return this.exampleInterface;
}
}
public class AbstractClassSubclass extends AbstractClass {
//Instead of the interface itself, I provide my constructor it's implementation
public AbstractClassSubclass(ExampleInterfaceImplementation exampleInterfaceImpl) {
super(exampleInterfaceImpl);
}
}
public class TestClass {
private void testMethod() {
AbstractClassSubclass test = new AbstractClassSubclass(
new ExampleInterfaceImplementation()
);
//Would return ExampleInterface, instead of ExampleInterfaceImplementation
test.getExampleInterface();
}
}
Update
I believe I have fixed this using type parameters.
I'm sure I have tried it before but had a few problems...
Now it works perfectly.

Abstract class and mandatory methods of childs?

I have this abstract base class and each of it's childs should have a specific mandatory function but slightly different. Is this possible using the abstract class or should I be using an interface for this?
I will be using the structure like this
public abstract class Animal
{
//Mandatory method
Public void sound()
{
}
}
public class Cat extends Animal
{
public void sound()
{
System.out.println("Miauw");
}
}
public class Dog extends Animal
{
public void sound()
{
System.out.println("Woof");
}
}
//I will put all these child objects in a List<Animal> and need to call these methods.
for (Animal a : animalList)
{
a.sound();
}
How would one go about this structure? I have to add that I am using an abstract class because there are plenty of identical methods that need to be shared among the child classes. Just some of the methods need to be different from each other but mandatory and accessible from the base class.
You are looking for:
public abstract class Animal
{
//Mandatory method
abstract public void sound();
}
But also look at other users advices:
use lowercase for method names
the keyword publicalways goes in lowercase
use interfaces if your Animal class hasn't common code for all children classes
Both an abstract class and an interface would work in this case. The times when you'd want to use an abstract class is when there are common methods and data that you want shared among all subclasses. Such as, if Animal had a weight variable, and each subclass sets that variable.
NOTE: In an abstract class, any methods that you don't want to implement, you must declare as abstract. See how I modified Sound() below. Also, a bonus tip is that the standards say that method names should start with a lowercase letter, so I changed Sound to sound.
public abstract class Animal
{
private int weight;
public void setWeight(int weight) {
this.weight = weight;
}
public int getWeight() {
return weight;
}
//Mandatory method
abstract public void sound();
}
public class Cat extends Animal
{
public Cat(int weight) {
this.setWeight(weight);
}
public void sound()
{
System.out.println("Miauw");
}
}
public class Dog extends Animal
{
public Dog(int weight) {
this.setWeight(weight);
}
public void sound()
{
System.out.println("Woof");
}
}
You are looking for Java's abstract modifier. The official Java Documentation contains more specific information about abstract and final here.
public abstract class Animal
{
// Mandatory method with no "default" implementation.
public abstract void Sound();
// Optional method with a default implementation.
public void Move() {
// some actions here
}
// Optional method with a fixed implementation (it can't be changed in a child class).
public final void Eat(Food food) {
// some actions here
}
}
you should use interface in this case because you are not defining any method, if you only want to provide declaration interface is ok for that
if you use abstract class you overhead by overriding the method and define it again

Java abstract class fields override

I have an abstract class that should implement a public field, this field is an interface or another abstract classe.
something like this:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
Now i have another specialized class Container:
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Java allow me to compile this, and i IMAGINE that the field child in SpecialContainer is automatically overloading the field child of the GenericContainer...
The questions are:
Am i right on this? The automatic 'overloading' of child will happen?
And, more important question, if i have another class like this:
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
test() will return 1 or 2? i mean the GenericContainer container field what prop1 will call, the generic or the special?
And what if the special prop1 was declared as String (yes java allow me to compile also in this case)?
Thanks!
In Java, data members/attributes are not polymorphic. Overloading means that a field will have a different value depending from which class it's accessed. The field in the subclass will hide the field in the super-class, but both exists. The fields are invoked based on reference types, while methods are used of actual object. You can try it yourself.
It's called, variable hiding/shadowing, for more details look on here
It isn't overriding anything, you're just hiding the original field at the current class scope. If you use a variable with the subtype you will still be able to access the original property. Example:
abstract class GenericContainer {
public GenericChild child;
}
abstract class GenericChild {
public int prop1=1 ;
}
class SpecialChild extends GenericChild {
public int prop1=2;
}
class SpecialContainer extends GenericContainer {
public SpecialChild child;
}
public class Main {
public static void main( String ... args ) {
GenericContainer container = new SpecialContainer();
container.child = new SpecialChild();
System.out.println( container.child.prop1 );
SpecialChild child = (SpecialChild) container.child;
System.out.println( child.prop1 );
}
}
This prints 1 and then 2.
From SpecialChild you would also be able to go up one level using super:
class SpecialChild extends GenericChild {
public int prop1=2;
public int getOriginalProp1() {
return super.prop1;
}
}
Regarding
....and i IMAGINE that the field "child" in SpecialContainer is automatically overloading the field 'child' of the GenericContainer...
No. Fields don't get overridden, only methods do.
This is one reason why use of (overridable) getter and setter methods are preferred to direct access to fields. Your fields should almost all be private.
As for your design, there's no need for your SpecialContainer class to have a SpecialChild field, but instead the SpecialChild object should be placed in the GenericChild field.
Why nobody is observing that program will throw NullPointerException.
subclass's field with same name will hide super class's field. There is no overriding with field. Overriding is only possible with methods.
Original Code by Author:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extend GenericChild {
public int prop1=2;
}
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
Java allow me to compile this, and i IMAGINE that the field "child" in
SpecialContainer is automatically overloading the field 'child' of the
GenericContainer...
Firstly, Inheritence doesn't apply to variables. Fields(Insatnce variables) are not overridden in your sub-class.they are only visible in your subclass if they are marked with either public, protected or default.
To answer your question it maintains both instances. And depending on how you refer to the container (either through the abstract or the impl) determines which variable you are referring to.
public class Test {
public abstract class Container{
public Generic gen = new Generic();
}
public class ContainerImpl extends Container{
public GenericImpl gen = new GenericImpl();
}
public class Generic{
public int prop = 0;
}
public class GenericImpl extends Generic{
public int prop = 1;
}
public Test(){
Container c = new ContainerImpl();
System.out.println(c.gen.prop); // Outputs "0"
System.out.println(((ContainerImpl)c).gen.prop); // Output "1"
}
public static void main(String[] args) {
new Test();
}
}
The bigger question at hand is, why would you design something like this? I'm assuming you are asking from a theoretical perspective.
My 2 cents, this isn't great OO design. You would be better off making the public variables private and assigning their values through a constructor or property setter. As-is, it will lead to unexpected results in your code.

java subclass have method to return its class

Ok, maybe this is a stupid question. But i'm just wondering if this can be done in java.
abstract public class ParentClass<T> {
abstract public T getTest();
}
in the subclass
public class SubClass extends ParentClass<MyObject> {
public MyObject getTest() {
// I can return the object with class MyObject
return null;
}
}
My question is can I return the class type in the child method? I mean, is it can be done by adding some code in the ParentClass, so I can do this below?
For example
public class Sub1Class extends parentClass<Object1> {
public Object1 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub1Class getItClassObject() { }
}
other example
public class Sub2Class extends parentClass<Object2> {
public Object2 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub2Class getItClassObject() { }
}
one example again
public class Sub3Class extends parentClass<Object3> {
public Object3 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub3Class getItClassObject() { }
}
if you see, method getItClassObject in Sub1Class, Sub2Class and Sub3Class will follow it's class. But I don't want to add same method for every subclass, just want to add some code (if feasible) in the ParentClasss, so in the subclass, I just can call getItClassObject directly without write all the code in every subclass.
Usually I add method in ParentClass like this.
abstract public class ParentClass<T> {
abstract public T getTest();
public Object getItClassObject() { }
}
so in the subclass I just instance the class, but I have to cast again :(
Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = (Sub1Class) sub1Class.getItClassObject();
Sub2Class sub2Class = new Sub2Class();
Sub2Class after2Cast = (Sub2Class) sub2Class.getItClassObject();
I think it cannot be done in java. But I don't know if there is a clue to solve this. Thanks
This is what you want I think. The following compiles:
abstract class A {
public abstract A getA();
}
class B extends A {
// Declared to return a B, but it still properly overrides A's method
#Override
public B getA() {
return new B();
}
}
class C extends A {
// Declared to return a B, but it still properly overrides A's method
#Override
public C getA() {
return new C();
}
}
As you can see, A declares that the getA() method returns an A. But, you can restrict the return type in subclasses as shown.
I'm not sure if I understand your intent correctly, but I think the built-in Object.getClass() method will do what you want. Given classes defined as:
public abstract class ParentClass<T> {
public abstract T getTest();
}
class SubClassString extends ParentClass<String> {
public String getTest() {
return "";
}
}
class SubClassInteger extends ParentClass<Integer> {
public Integer getTest() {
return Integer.valueOf(0);
}
}
getClass() will return the correct run-time class
public static void main(String[] args) {
SubClassString subString = new SubClassString();
// displays "class SubClassString"
System.out.println(subString.getClass());
SubClassInteger subInteger = new SubClassInteger();
// displays "class SubClassInteger"
System.out.println(subInteger.getClass());
ParentClass<?> parentInstance = new SubClassInteger();
// displays "class SubClassInteger"
System.out.println(parentInstance.getClass());
}
The only way I can think of is by telling the parent class what the subclass is when you extend it (just like you did with 'T'). Eg:
public abstract class ParentClass<T,U> {
abstract public T getTest();
abstract public U getItClassObject();
}
They you define your subclass like so:
public class Sub1Class extends ParentClass<Object1,Sub1Class> {
public Object1 getTest() { }
public Sub1Class getItClassObject() { }
}
Then you can do what you want without the typecast:
Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = sub1Class.getItClassObject();
If your objects have no-arg constructors (or some consistent form of constructor across all of them), you can use reflection to do it. Some pseudocode would be
public class MyClass {
public MyClass instantiateType() {
Class<?> actualClass = getClass();
return actualClass.newInstance();
}
}
This is using the runtime type of the class, so subclasses will return their type. This works only for a no-arg constructor though.

Categories

Resources