Child method from superclass (java) - java

I have a superclass, let's say BaseClass and two subclasses, let's say SubclassA and SubclassB, they don't have any other relationship between them but their parent class.
At a lot of places in my code I need to call to methods that both the subclasses have but not the parentclass... And I find myself repeating a lot of code which looks like:
if (obj instanceof SubclassA) {
// stuff
} else if (obj instanceof SubclassB) {
// same stuff
}
The first idea should be to put that "stuff" into a method in superclass, but I can't as that superclass is parent to other subclasses that don't have that behavior...
So... is there a way to avoid repeating aaaalll of that code?
Maybe a common superclass for both subclasses that is a subclass itself of superclass?

I would suggest extracting the method as an abstract method in the parent(if the parent is abstract), or just a method that will be overridden in child classes. If this is not possible, or desirable I would suggest adding a common abstract class that extends the parent that has just the method that is common to both subclasses, that will be then extended by the two subclasses.
If adding and changing the parent class might be an issue, you can do the same thing by using an interface that is then implemented by both subclasses and where you need to call your code you will just cast to the given interface and call the needed method.
Something like this:
interface CommonInterface {
void commonMethod();
}
class SubClassB implements CommonInterface {
void commonMethod() {
// implementation
}
}
class SubClassA implements CommonInterface {
void commonMethod() {
// implementation
}
}
//...
if (obj instanceof CommonInterface) {
((CommonInterface)object).stuffCall();
}

Add the method to the super class.
Make it with an empty body.
In SubClassA override it, implement the logic you need.
In SubClassB override it, implement the logic you need.
Then in your calling code, instead of doing
if (obj instanceof SubclassA) {
obj.method();
} else if (obj instanceof SubclassB) {
obj.method();
}
just do this
obj.method();
provided obj is declared as an instance of the parent class.
The empty method body in the super class guarantees you have
no issues with this "but I can't as that super class is parent
to other subclasses that don't have that behavior".
So the idea is that you will have empty behavior
in the super class and in all the sub classes which
do not explicitly override this method.

Firstly, the concept of polymorphism is to do away with the need to check the type of an object before calling methods on it. So, this should not be necessary in an OO-language.
Secondly, the reason why you might use an abstract parent class over an interface would but because there is some shared functionality between sub-types (subclasses). So, if there is shared, common functionality between SubclassA and SubclassB then leave your superclass intact, otherwise switch it to an interface.
Likewise, and as you suggest yourself, if SubclassA and SubclassB have a common behaviour (but their own implementation) then utilise a separate API (if other sub-types of BaseClass do not also share that behaviour (your #doStuff call).
In this case, I'd introduce interface Stuff containing method #doStuff and have both my SubclassA and SubclassB implement it, each providing it's own implementation. Your clients can then treat your obj instance as a Stuff, irrespective of it's real type and polymorphism will do the rest.
interface Stuff {
void doStuff();
}
public class SubclassA extends BaseClass implements Stuff {
// Does it need BaseClass still?
public doStuff() {
...
}
}
public class SubclassB extends BaseClass implements Stuff {
// Does it need BaseClass still?
public doStuff() {
...
}
}
// Example client code...
public class MyStuffClient {
Stuff s = new SubclassA();
...
public void onStuff() {
s.doStuff();
}
}
Decide if you really need the suer class BaseClass.

What about the following two ways:
Declare the target method in super class and provide a default implementation(e.g. empty method, do nothing) as well. Subclass will override that behavior if needed.
Declare the target method in a Interface, and make SubclassA and SubclassB implementation of the interface. The super class and other subclasses don't need to implement the interface.

If SubClassA and SubClassB have some behaviour that isnt present in Subclass C, D, E etc then just introduce an intermediate class between the parent and A and B. C, D etc derive from the parent, And B derive from the new class, which contains functionality that A and B share.

You can make the method on the superclass protected. For example, you can do this on SuperClass:
package test;
public SuperClass {
protected void myMethod() {
...stuff...
}
}
exposing on SubclassA
package test;
public SubclassA extends SuperClass {
public void myMethod() {
super.myMethod();
}
}
and hiding on SubclassB (just not override it)
package test;
public SubclassB extends SuperClass {
}
From a different package, protected methods are not visible unless the class override it changing its visibility modifier.
Source: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Related

Could not instantiate the type (Class)? [duplicate]

What is an "abstract class" in Java?
An abstract class is a class which cannot be instantiated. An abstract class is used by creating an inheriting subclass that can be instantiated. An abstract class does a few things for the inheriting subclass:
Define methods which can be used by the inheriting subclass.
Define abstract methods which the inheriting subclass must implement.
Provide a common interface which allows the subclass to be interchanged with all other subclasses.
Here's an example:
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
Notice that "abstractMethod()" doesn't have any method body. Because of this, you can't do the following:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
There's no method that implements abstractMethod()! So there's no way for the JVM to know what it's supposed to do when it gets something like new ImplementingClass().abstractMethod().
Here's a correct ImplementingClass.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
Notice that you don't have to define implementedMethod() or finalMethod(). They were already defined by AbstractClass.
Here's another correct ImplementingClass.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
In this case, you have overridden implementedMethod().
However, because of the final keyword, the following is not possible.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
public void finalMethod() { System.out.print("ERROR!"); }
}
You can't do this because the implementation of finalMethod() in AbstractClass is marked as the final implementation of finalMethod(): no other implementations will be allowed, ever.
Now you can also implement an abstract class twice:
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("second abstractMethod()"); }
}
Now somewhere you could write another method.
public tryItOut()
{
ImplementingClass a = new ImplementingClass();
AbstractClass b = new ImplementingClass();
a.abstractMethod(); // prints "abstractMethod()"
a.implementedMethod(); // prints "Overridden!" <-- same
a.finalMethod(); // prints "finalMethod()"
b.abstractMethod(); // prints "abstractMethod()"
b.implementedMethod(); // prints "Overridden!" <-- same
b.finalMethod(); // prints "finalMethod()"
SecondImplementingClass c = new SecondImplementingClass();
AbstractClass d = new SecondImplementingClass();
c.abstractMethod(); // prints "second abstractMethod()"
c.implementedMethod(); // prints "implementedMethod()"
c.finalMethod(); // prints "finalMethod()"
d.abstractMethod(); // prints "second abstractMethod()"
d.implementedMethod(); // prints "implementedMethod()"
d.finalMethod(); // prints "finalMethod()"
}
Notice that even though we declared b an AbstractClass type, it displays "Overriden!". This is because the object we instantiated was actually an ImplementingClass, whose implementedMethod() is of course overridden. (You may have seen this referred to as polymorphism.)
If we wish to access a member specific to a particular subclass, we must cast down to that subclass first:
// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();
Lastly, you cannot do the following:
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
Only one class can be extended at a time. If you need to extend multiple classes, they have to be interfaces. You can do this:
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
Here's an example interface:
interface InterfaceA
{
void interfaceMethod();
}
This is basically the same as:
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
The only difference is that the second way doesn't let the compiler know that it's actually an interface. This can be useful if you want people to only implement your interface and no others. However, as a general beginner rule of thumb, if your abstract class only has abstract methods, you should probably make it an interface.
The following is illegal:
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
You cannot implement methods in an interface. This means that if you implement two different interfaces, the different methods in those interfaces can't collide. Since all the methods in an interface are abstract, you have to implement the method, and since your method is the only implementation in the inheritance tree, the compiler knows that it has to use your method.
A Java class becomes abstract under the following conditions:
1. At least one of the methods is marked as abstract:
public abstract void myMethod()
In that case the compiler forces you to mark the whole class as abstract.
2. The class is marked as abstract:
abstract class MyClass
As already said: If you have an abstract method the compiler forces you to mark the whole class as abstract. But even if you don't have any abstract method you can still mark the class as abstract.
Common use:
A common use of abstract classes is to provide an outline of a class similar like an interface does. But unlike an interface it can already provide functionality, i.e. some parts of the class are implemented and some parts are just outlined with a method declaration. ("abstract")
An abstract class cannot be instantiated, but you can create a concrete class based on an abstract class, which then can be instantiated. To do so you have to inherit from the abstract class and override the abstract methods, i.e. implement them.
A class that is declared using the abstract keyword is known as abstract class.
Abstraction is a process of hiding the data implementation details, and showing only functionality to the user. Abstraction lets you focus on what the object does instead of how it does it.
Main things of abstract class
An abstract class may or may not contain abstract methods.There can be non abstract methods.
An abstract method is a method that is declared without an
implementation (without braces, and followed by a semicolon), like this:
ex : abstract void moveTo(double deltaX, double deltaY);
If a class has at least one abstract method then that class must be abstract
Abstract classes may not be instantiated (You are not allowed to create object of Abstract class)
To use an abstract class, you have to inherit it from another class. Provide implementations to all the abstract methods in it.
If you inherit an abstract class, you have to provide implementations to all the abstract methods in it.
Declare abstract class
Specifying abstract keyword before the class during declaration makes it abstract. Have a look at the code below:
abstract class AbstractDemo{ }
Declare abstract method
Specifying abstract keyword before the method during declaration makes it abstract. Have a look at the code below,
abstract void moveTo();//no body
Why we need to abstract classes
In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and many other graphic objects. These objects all have certain states (for ex -: position, orientation, line color, fill color) and behaviors (for ex -: moveTo, rotate, resize, draw) in common. Some of these states and behaviors are the same for all graphic objects (for ex : fill color, position, and moveTo). Others require different implementation(for ex: resize or draw). All graphic objects must be able to draw or resize themselves, they just differ in how they do it.
This is a perfect situation for an abstract superclass. You can take advantage of the similarities, and declare all the graphic objects to inherit from the same abstract parent object (for ex : GraphicObject) as shown in the following figure.
First, you declare an abstract class, GraphicObject, to provide member variables and methods that are wholly shared by all subclasses, such as the current position and the moveTo method. GraphicObject also declared abstract methods, such as draw or resize, that need to be a implemented by all subclasses but must be implemented in different ways. The GraphicObject class can look something like this:
abstract class GraphicObject {
void moveTo(int x, int y) {
// Inside this method we have to change the position of the graphic
// object according to x,y
// This is the same in every GraphicObject. Then we can implement here.
}
abstract void draw(); // But every GraphicObject drawing case is
// unique, not common. Then we have to create that
// case inside each class. Then create these
// methods as abstract
abstract void resize();
}
Usage of abstract method in sub classes
Each non abstract subclasses of GraphicObject, such as Circle and Rectangle, must provide implementations for the draw and resize methods.
class Circle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
class Rectangle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
Inside the main method you can call all methods like this:
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
Ways to achieve abstraction in Java
There are two ways to achieve abstraction in java
Abstract class (0 to 100%)
Interface (100%)
Abstract class with constructors, data members, methods, etc
abstract class GraphicObject {
GraphicObject (){
System.out.println("GraphicObject is created");
}
void moveTo(int y, int x) {
System.out.println("Change position according to "+ x+ " and " + y);
}
abstract void draw();
}
class Circle extends GraphicObject {
void draw() {
System.out.println("Draw the Circle");
}
}
class TestAbstract {
public static void main(String args[]){
GraphicObject grObj = new Circle ();
grObj.draw();
grObj.moveTo(4,6);
}
}
Output:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
Remember two rules:
If the class has few abstract methods and few concrete methods,
declare it as an abstract class.
If the class has only abstract methods, declare it as an interface.
References:
TutorialsPoint - Java Abstraction
BeginnersBook - Java Abstract Class Method
Java Docs - Abstract Methods and Classes
JavaPoint - Abstract Class in Java
It's a class that cannot be instantiated, and forces implementing classes to, possibly, implement abstract methods that it outlines.
Simply speaking, you can think of an abstract class as like an Interface with a bit more capabilities.
You cannot instantiate an Interface, which also holds for an abstract class.
On your interface you can just define the method headers and ALL of the implementers are forced to implement all of them. On an abstract class you can also define your method headers but here - to the difference of the interface - you can also define the body (usually a default implementation) of the method. Moreover when other classes extend (note, not implement and therefore you can also have just one abstract class per child class) your abstract class, they are not forced to implement all of your methods of your abstract class, unless you specified an abstract method (in such case it works like for interfaces, you cannot define the method body).
public abstract class MyAbstractClass{
public abstract void DoSomething();
}
Otherwise for normal methods of an abstract class, the "inheriters" can either just use the default behavior or override it, as usual.
Example:
public abstract class MyAbstractClass{
public int CalculateCost(int amount){
//do some default calculations
//this can be overriden by subclasses if needed
}
//this MUST be implemented by subclasses
public abstract void DoSomething();
}
From oracle documentation
Abstract Methods and Classes:
An abstract class is a class that is declared abstract—it may or may not include abstract methods
Abstract classes cannot be instantiated, but they can be subclassed
An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:
abstract void moveTo(double deltaX, double deltaY);
If a class includes abstract methods, then the class itself must be declared abstract, as in:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract.
Since abstract classes and interfaces are related, have a look at below SE questions:
What is the difference between an interface and abstract class?
How should I have explained the difference between an Interface and an Abstract class?
Get your answers here:
Abstract class vs Interface in Java
Can an abstract class have a final method?
BTW - those are question you asked recently. Think about a new question to build up reputation...
Edit:
Just realized, that the posters of this and the referenced questions have the same or at least similiar name but the user-id is always different. So either, there's a technical problem, that keyur has problems logging in again and finding the answers to his questions or this is a sort of game to entertain the SO community ;)
Little addition to all these posts.
Sometimes you may want to declare a
class and yet not know how to define
all of the methods that belong to that
class. For example, you may want to
declare a class called Writer and
include in it a member method called
write(). However, you don't know how to code write() because it is
different for each type of Writer
devices. Of course, you plan to handle
this by deriving subclass of Writer,
such as Printer, Disk, Network and
Console.
An abstract class can not be directly instantiated, but must be derived from to be usable. A class MUST be abstract if it contains abstract methods: either directly
abstract class Foo {
abstract void someMethod();
}
or indirectly
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
However, a class can be abstract without containing abstract methods. Its a way to prevent direct instantation, e.g.
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
The latter style of abstract classes may be used to create "interface-like" classes. Unlike interfaces an abstract class is allowed to contain non-abstract methods and instance variables. You can use this to provide some base functionality to extending classes.
Another frequent pattern is to implement the main functionality in the abstract class and define part of the algorithm in an abstract method to be implemented by an extending class. Stupid example:
abstract class Processor {
protected abstract int[] filterInput(int[] unfiltered);
public int process(int[] values) {
int[] filtered = filterInput(values);
// do something with filtered input
}
}
class EvenValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove odd numbers
}
}
class OddValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove even numbers
}
}
Solution - base class (abstract)
public abstract class Place {
String Name;
String Postcode;
String County;
String Area;
Place () {
}
public static Place make(String Incoming) {
if (Incoming.length() < 61) return (null);
String Name = (Incoming.substring(4,26)).trim();
String County = (Incoming.substring(27,48)).trim();
String Postcode = (Incoming.substring(48,61)).trim();
String Area = (Incoming.substring(61)).trim();
Place created;
if (Name.equalsIgnoreCase(Area)) {
created = new Area(Area,County,Postcode);
} else {
created = new District(Name,County,Postcode,Area);
}
return (created);
}
public String getName() {
return (Name);
}
public String getPostcode() {
return (Postcode);
}
public String getCounty() {
return (County);
}
public abstract String getArea();
}
What is Abstract class?
Ok! lets take an example you known little bit about chemistry we have an element carbon(symbol C).Carbon has some basic atomic structure which you can't change but using carbon you can make so many compounds like (CO2),Methane(CH4),Butane(C4H10).
So Here carbon is abstract class and you do not want to change its basic structure however you want their childrens(CO2,CH4 etc) to use it.But in their own way
An abstract class is a class that is declared abstract — it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
In other words, a class that is declared with abstract keyword, is known as abstract class in java. It can have abstract(method without body) and non-abstract methods (method with body).
Important Note:-
Abstract classes cannot be used to instantiate objects, they can be used to create object references, because Java's approach to run-time Polymorphism is implemented through the use of superclass references. Thus, it must be possible to create a reference to an abstract class so that it can be used to point to a subclass object. You will see this feature in the below example
abstract class Bike{
abstract void run();
}
class Honda4 extends Bike{
void run(){
System.out.println("running safely..");
}
public static void main(String args[]){
Bike obj = new Honda4();
obj.run();
}
}
An abstract class is one that isn't fully implemented but provides something of a blueprint for subclasses. It may be partially implemented in that it contains fully-defined concrete methods, but it can also hold abstract methods. These are methods with a signature but no method body. Any subclass must define a body for each abstract method, otherwise it too must be declared abstract.
Because abstract classes cannot be instantiated, they must be extended by at least one subclass in order to be utilized. Think of the abstract class as the generic class, and the subclasses are there to fill in the missing information.
Class which can have both concrete and non-concrete methods i.e. with and without body.
Methods without implementation must contain 'abstract' keyword.
Abstract class can't be instantiated.
It do nothing, just provide a common template that will be shared for it's subclass

Is it possible for a superclass object to refer a subclass member method which is not inherited?

In dynamic method binding a superclass reference can only call a subclass method which is inherited and overrode by it. However, the otherwise can be implemented.
abstract class in
{
abstract void print();
}
class a extends in
{
String name=this.getClass().getSimpleName();
void show()
{
System.out.println("class "+name);
}
void print()
{
show();
}
}
class Main
{
public static void main(String args[])
{
in x;
x = new a();
x.print();
}
}
Here, it prints successfully
class a
Also getClass() returns the subclass name instead of superclass name as this refers to the superclass object in main method.
A parent object reference is just constrained by the methods that it has in its class definition. If those methods are overridden by subclass, and at run time, if the actual object referred by the parent reference is of subclass type, then that overridden method is invoked. It doesn't matter if the overridden method invokes methods that are not originally present in the parent class or accesses the variables that are not present in the parent class.
This is what polymorphism is all about. It is by design meant to be this way as it makes program extension easier in case if we have different specific inheritance hierarchies where the parent class need not know the exact implementation of certain methods and can make things implemented by the subclasses as some sort of contract.
Future is unknown A developer writing a class A.java today can never predict in future the names or signatures of the methods which any other developer may include in his class extending A.java. Also such classes may be numerous with each having separate methods.
Base class should never be coupled with its sub classes. It must not care about how the sub classes are implemented.
Although it is not recommended but still if you wish to invoke the method defined in one of the sub class you may do it by typecasting like below.
public class Parent {
public class someMethod(){
if( this instanceof Child1){
((Child1)this).someAdditionalMethod();
}
}
}
public class Child1 extends Parent{
public class someAdditionalMethod(){
}
}

how to copy SubClass object in BaseClass copy constructor

I would like to make copy of SubClass object in BaseClass constructor. I need that the following code execute correctly.
class BaseClass{
BaseClass() {}
BaseClass(BaseClass base) {
//TODO: how to implement?
}
}
class SubClass extends BaseClass {
SubClass() {}
}
public class Test {
public static void main(String[] args) {
BaseClass sub = new SubClass();
BaseClass subCopy = new BaseClass(sub);
if (subCopy instanceof SubClass) {
// need to be true
}
}
}
Is it even possible? If yes how can I do it? Else how can I get similar effect?
It's not possible. A constructor of class A gives you an instance of A, no way to circumvent this. Why not instantiate the subclass explicitly?
Another possibility might involve a static factory method like:
public static BaseClass create(BaseClass input) {
// return BaseClass or subclass
}
It seems like you want the object of BaseClass to be an instance of SubClass which extends BaseClass.
Is it even possible?
-No. It is not possible.
The instanceof operator returns true if the variable on left side satisfies IS-A condition of the variable or class on the left side.
The SubClass IS-A BaseClass since it extends BaseClass. But the BaseClass can never be a SubClass, since it can't extend SubClass.
You seems to be having a design upside-down. If you need to do what you are asking then you need to re-think over your design. Ideally in your subclass constructor, you should be copying or initializing the base class properties by calling super().

Can I know the extending class from the super class in Java?

I have the following classes.
public class Super{
public static void useSubClass(){
//I want to access the sub class object here, how.
}
}
public class Sub1 extends Super{
}
public class Sub2 extends Super{
}
I want to access the sub-class object from a static method in super-class. i.e. When I call Sub1.useSubClass() the method has access to Sub1.class and when I use Sub2.useSubClass(), I can access the Sub2.class.
Is there any way to access the sub-class object from super-class.
In general, you cannot do that from a superclass (and shouldn't!) because you won't know (and shouldn't assume anything about!) what classes will inherit from your superclass.
Depending on exactly what you want to do, there are alternatives, such as:
Use the template pattern to define "filler methods" that your subclasses must implement; these filler methods will be called by the template method in your superclass.
Define methods to be overridden by your subclass.
Define interfaces to be implemented by your subclass.
Update: As #JB Nizet has pointed out, I might have misread the question.
Here's something (very similar to the Observer Pattern) you can do if you wish to access subclasses from the static method in your superclass:
Define a static listener list in your superclass, call it List observerList
In the constructor of your superclass, add the class instance itself to that static observerList
For all subclasses, it is their responsibility to call super() from their constructors in order to register themselves to observerList (and unregister in deconstructor)
Then in your superclass's static useSubClass() method, you can iterate through that list of subclass instances, find the particular one you care about (maybe specified by some argument), and then do something with it.
Static methods are not inherited, and calling Sub2.useSubClass() is strictly equivalent to calling Super.useSubclass().
There is no way to get this information, because it doesn't exist. The compiler allows calling Sub2.useSubclass(), but translates it into Super.useSubclass().
public static void useSubClass(Super sub) {
if (sub instanceof Sub1) {
// Do something
} else if (sub instanceof Sub2) {
// Do something else
} else {
// Something else is extending Super
}
}
However, a better question is why? Can't you simply override the method in your subclass?
No you cannot because the super-class cannot know the methods of the sub-classes.
You should consider to create a new class which sees both super-class and sub-classes and implement the static method inside this new class
For the record, you could do this in Python, using class methods:
class super(object):
#classmethod
def usesubclass(cls):
print cls
class sub1(super):
pass
class sub2(super):
pass
Using this code, you could call sub1.usesubclass() or sub2.usesubclass(), and that would print the representations of the sub1 and sub2 classes, respectively:
>>> sub1.usesubclass()
<class '__main__.sub1'>
>>> sub2.usesubclass()
<class '__main__.sub2'>
Java, however, does not support such mechanisms, unfortunately. When you compile Sub1.useSubClass() in your example, the compiler will simply use Sub1 as the basic namespace to look up the the useSubClass() method in Super, but no information on that is actually compiled into code. In the resulting bytecode, the call is simply one directly to Super.useSubClass() and nothing more.
I sympathize with your plight, but Java is what it is. The closest thing you could come, I think, would be the following code:
public class Super {
public static <T extends Super> void useSubClass(Class<T> sub) {
}
}
And then call that method explicitly as either Super.useSubClass(Sub1.class) or Super.useSubClass(Sub2.class).
I figured something out. It works if implemented with care.
/** SuperClass.java **/
public abstract class SuperClass {
public static void printClass(){
System.out.println(new ImplementingClassRetriever().getCallingClass());
}
static class ImplementingClassRetriever extends SecurityManager{
public Class getCallingClass() {
Class[] classes = getClassContext();
for (Class clazz : classes) {
if (SuperClass.class.isAssignableFrom(clazz) && clazz != null
&& !clazz.equals(SuperClass.class)) {
return clazz;
}
}
return null;
}
}
}
/** Main.java **/
public class Main{
public static void main(String[] args) {
Sub.printClass(); //this does not work
Sub.testStaticCall(); //this works!! :)
}
}
class Sub extends SuperClass{
public static void testStaticCall(){
Sub.printClass(); //calling the method in the super class
}
}
This is just a toy example. The super class contains a static class that contains a method to retrieve the calling class.
In the subclass I have another static method which calls the superclass's method for printing the class name.
The Main class/function contains two calls to Sub's inherited and locally implemented method. The first call prints null, because the calling context (i.e. Main) is not a subclass of Super However the delegate method in Sub works because the calling context is now a subclass of SuperClass and hence the calling class can be determined.
Although You can create a reference to the super class and point it to any sub-class. This can also be done dynamically during run-time. This is a way of run-time polymorphism.

Same method in Interface and Abstract class

I came to situation :
public interface Intr {
public void m1();
}
public abstract class Abs {
public void m1() {
System.out.println("Abs.m1()");
}
// public abstract void m1();
}
public class A extends Abs implements Intr {
#Override
public void m1() {
// which method am I overriding, well it is Abs.m1() but why?
// if method implemented is Abs.m1(), then why I am not getting error for Intr.m1() not implemented.
}
}
You are satisfying both conditions at once; ie. the one implementation is at the same time fulfilling the abstract class requirements and the interface requirements.
As a note, unless you are using Intr in another inheritance chain, you don't need it. Also, it might make sense to move the implements Intr up to the abstract class definition.
You can only override methods defined in another class.
Methods declared in an interface are merely implemented. This distinction exists in Java to tackle the problem of multiple inheritance. A class can only extend one parent class, therefore any calls to super will be resolved without ambiguity. Classes however can implement several interfaces, which can all declare the same method. It's best to think of interfaces as a list of "must have"s: to qualify as a Comparable your cluss must have a compareTo() method but it doesn't matter where it came from or what other interfaces require that same method.
So technically you override Abs.m1() and implement Intr.m1() in one fell swoop.
Note that this would be fine too:
public class B extends Abs implements Intr {
//m1() is inherited from Abs, so there's no need to override it to satisfy the interface
}
Here, both the interface and abstract class have the same method.
You have one class with named Derived which extends an abstract class and implement an interface. It's true and you override print method on Derived class it's fine and it compiles correctly and does not give any error but here you can't identify which class method is overridden like abstract class or interface.
This is runtime polymorphism you can't create an instance of an abstract class or interface but you can create a reference variable of that type. Here the solution is you can't identify that on compile-time it's actually overridden at run time.
interface AnInterface
{
public void print();
}
abstract class Base
{
public abstract void print();
}
public class Derived extends Base implements AnInterface
{
public void print(){
System.out.println("hello");
}
AnInterface iRef = new Derived();
iRef.print(); // It means interface method is overridden and it's decided when we call the method.
Base base = new Derived();
base.print(); // It means abstract class method is overridden.
}
#Override ensures you override the method with no difference Interface or abstract superclass. So no error with override.
On the other hand Interface method is also implemented in the superclass which is enough for Interface contracts.

Categories

Resources