I have question that is more or less technical. I would like to do the following:
Have a class that will define both a default constructor and another constructor that will create a new object called NamedRunnable.
This class will effectively implement the Runnable interface thus including the run method that it provides.
I want to find a way to no explicitly implement the run method within the the 'NamedRunnable' class itself but have it implemented within all member that will subclass the said class.
Is something like this possible?
If this is something you meant, then yes it is possible :)
public class NamedRunnable implements Runnable {
public NamedRunnable(String name) {
// ....
}
public void run() {
// ...,
}
}
It sounds like you want an abstract class (can't be instantiated) that implements Runnable:
abstract class NamedRunnable implements Runnable {
private String name;
protected NamedRunnable(String _name) {
this.name = _name;
}
}
Note that that doesn't implement run. run is implicitly abstract in that class, as though you had included
abstract public void run();
...because we declare the interface but don't implement it (which we wouldn't be allowed to do if the class weren't declared abtract).
You'd use that as a base class for a concrete class, e.g.:
class Thingy extends NamedRunnable {
public Thingy(String name) {
super(name);
}
#Override
public void run() {
// ...
}
}
The concrete class has the run implementation, and can be instantiated.
Related
In my project I have a superclass and two subclasses extending from it. There is a method in the superclass that is overriden differently in each subclass.
I want to know if it's possible to introduce a method (in another class) that takes object of either subclass as a parameter and calls a method overriden in one of subclasses (depending on to which subclass does the object belong).
public class Superclass{
public int method(){return 0;}
}
public class Subclass1 extends Superclass{
public int method(){return 1;}
}
public class Subclass2 extends Superclass{
public int method(){return 2;}
}
public class CallingClass{
public static int dependantCall(Superclass parameter){return parameter.method}
I want to be able to do something like
Subclass1 subclassObject = new Subclass1;
System.out.println(CallingClass.dependantCall(subclassObject));
and get output
1
That is what Polymorphism is for! Defining the Superclass as a parameter type will allow you to pass either subclass in.
For example in your other class you can define it like this:
// classes Dog and Cat extend Animal and override makeNoise()
class Owner{
playWith(Animal a){
a.makeNoise();
}
}
Now the Owner can accept owner.makeNoise(cat) and owner.makeNoise(dog)
More reading: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
Yes, it is entirely possible. Here's how that method would look like:
public <T extends Superclass> void foo(T subclassObject) {
...
}
Or:
public void foo(Superclass obj) {
...
}
Note that in the above method, you can pass subclasses' objects as well (they are covariant data types).
This is what Java does by default when you create subclases, so no need to do anything special. Each object carries it's type information at run time, and the method invoked would always be the most specific one for the object. Example:
public class Doer {
public void doSomething() {
// Body presence
};
}
public class Painter extends Doer {
#Override
public void doSomething() {
// Paint here
}
}
public class Manager extends Doer {
#Override
public void doSomething() {
// Micromanage here
}
}
// Elsewhere in your code:
public void busyness(Doer doer) {
doer.doSomething();
}
A style note: if it is possible, one should prefer using interfaces instead of base classes (base classes those should be used only if you want to share implementation between subclasses). Example with interfaces:
public interface Doer {
void doSomething();
}
public class JackOfAllTrades implements Does {
#Override
public void doSomething() {
// Do whatever necessary
}
}
// Client code stays exactly the same as above:
public void busyness(Doer doer) {
doer.doSomething();
}
Note that in Java a class can have only one base class but can implement multiple interfaces.
#Override annotations are not strictly required, but they help Java compiler to spot some errors for you (e.g. if you misprint method name).
In your example it would look like
public class CallingClass {
public static int dependantCall(Superclass parameter) {
return parameter.method();
}
}
Subclass1 subclassObject = new Subclass1();
System.out.println(CallingClass.dependantCall(subclassObject));
Im implementing a strategy pattern and in a specific situation, one strategy must use another strategy implementation as part of it.
For Example:
interface ProcessStrategy{
void process();
}
public class ProcessOnFile implements ProcessStrategy{
void process(){
}
}
public class ProcessOnFileNetwork implements ProcessStrategy{
void process(){
}
}
In this case, processOnFileNetwork will encapsulate the logic inside ProcessOnFile plus some especific logic..
How can i add this functionality without repeat the code??
Thanks !
You could use abstract class concept.
public abstract class ProcessStrategy{
public void process(){
// Common code goes here
}
}
public class ProcessOnFile extends ProcessStrategy{
public void process(){
super();
// Class specific code goes here
}
}
public class ProcessOnFileNetwork extends ProcessStrategy{
public void process(){
super();
// Class specific code goes here
}
}
Note abstract classes can have data variables too which can be utilized.
You can make ProcessOnFileNetwork a subclass of ProcessOnFile. That way, you can access the logic in the process() method of ProcessOnFile by calling super.process() in the process() method of ProcessOnFileNetwork.
You probably just typed your code in your question, but just in case, interface and implements must be all lowercase.
Greetings and salutations!
I currently have an abstract class A, and many classes subclassing it. The code is common to all the subclasses I've put in the oneMethod() and the code that's specific to each implementation I've put into two abstract methods.
public abstract class AbstractA {
public oneMethod() {
//do some intelligent stuff here
abstractMethodOne();
abstractMethodTwo();
}
protected abstract void abstractMethodOne();
protected abstract void abstractMethodTwo();
}
I have a class that overrides the oneMethod() method.
public class B extends AbstractA {
#Override
public oneMethod() {
//do some other intelligent stuff here
}
}
Is there any way to skip making a stub implementation of the two abstract methods in the subclass? I mean the only place they're used is in the overridden method.
Any help is appreciated!
No. If you extend an abstract class, you must either make the child class abstract or it must fulfill the contract of the parent class.
As a design observation, I would suggest that you try to make oneMethod() either final or abstract. It's hard to maintain programs that allow extension the way you're implementing it. Use other abstract methods to give child classes hooks into the functionality of oneMethod().
You have to provide an implementation to all abstract methods. Even if no part of the program calls them now a class can be created in the future that does call them, or the super class implementation may be changed. A stub is needed even if it's just for binary compatibility.
Just make class B also abstract.
public abstract class B extends AbstractA {
You could pull oneMethod up into a superclass:
public abstract class AbstractC {
public void oneMethod() {
}
}
public abstract class AbstractA extends AbstractC {
#Override
public void oneMethod() {
//do some intelligent stuff here
abstractMethodOne();
abstractMethodTwo();
}
protected abstract void abstractMethodOne();
protected abstract void abstractMethodTwo();
}
public class B extends AbstractC {
#Override
public void oneMethod() {
//do some other intelligent stuff here
}
}
see now how you don't need any more in AbstractC than you need.
Since abstractMethodOne() and abstractMethodTwo() are implementation specific but you know that you will always call them you can use composition like this:
public interface SomeInterface {
void abstractMethodOne();
void abstractMethodTwo();
}
and create a class like this:
public class SomeClass {
public void executeThem(SomeInterface onSomeObject) {
onSomeObject.abstractMethodOne();
onSomeObject.abstractMethodTwo();
}
}
then you can compose this in any of your classes where you should call those methods like this:
public class SomeImplementation implements SomeInterface {
public void abstractMethodOne() {
// ...
}
public void abstractMethodTwo() {
// ...
}
public void executeThem() {
new SomeClass().executeThem(this);
}
}
This way you got rid of the inheritance altogether and you can be more flexible in your classes implementing SomeInterface.
If your classes B and A have to implement their own oneMethod it's maybe because there are not in an inheritance link but they just should implement the same interface ?
Well, if abstractMethodTwo and abstractMethodOne are implementation specific, why you put these methods in the base abstract class ? Maybe a common interface or some specific design-pattern is what you're looking for!
An abstract method from an abstract class can be used in a class in the way shown below. I would appreciate your opinion if you find any wrong in my answer. Thank you.
Code using Java
public abstract class AbstractClassA {
protected abstract void method1();
public abstract void method2();
}
public class ClassB extends AbstractClassA{
#Override
protected void method1(){}
public void method2(){}
}
How do I create an object of an abstract class and interface? I know we can't instantiate an object of an abstract class directly.
You can not instantiate an abstract class or an interface - you can instantiate one of their subclasses/implementers.
Examples of such a thing are typical in the use of Java Collections.
List<String> stringList = new ArrayList<String>();
You are using the interface type List<T> as the type, but the instance itself is an ArrayList<T>.
To create object of an abstract class just use new just like creating objects of other non abstract classes with just one small difference, as follows:
package com.my.test;
public abstract class MyAbstractClass {
private String name;
public MyAbstractClass(String name)
{
this.name = name;
}
public String getName(){
return this.name;
}
}
package com.my.test;
public class MyTestClass {
public static void main(String [] args)
{
MyAbstractClass ABC = new MyAbstractClass("name") {
};
System.out.println(ABC.getName());
}
}
In the same way You can create an object of interface type, just as follows:
package com.my.test;
public interface MyInterface {
void doSome();
public abstract void go();
}
package com.my.test;
public class MyTestClass {
public static void main(String [] args)
{
MyInterface myInterface = new MyInterface() {
#Override
public void go() {
System.out.println("Go ...");
}
#Override
public void doSome() {
System.out.println("Do ...");
}
};
myInterface.doSome();
myInterface.go();
}
}
There are two ways you can achieve this.
1) Either you extend / implement the Abstract class / interface in a new class, create the object of this new class and then use this object as per your need.
2) The Compiler allows you to create anonymous objects of the interfaces in your code.
For eg. ( new Runnable() { ... } );
Hope this helps.
Regards,
Mahendra Liya.
You can provide an implementation as an anonymous class:
new SomeInterface() {
public void foo(){
// an implementation of an interface method
}
};
Likewise, an anonymous class can extend a parent class instead of implementing an interface (but it can't do both).
public abstract class Foo { public abstract void foo(); }
public interface Bar { public void bar(); }
public class Winner extends Foo implements Bar {
#Override public void foo() { }
#Override public void bar() { }
}
new Winner(); // OK
"instantiate" means "create an object of".
So you can't create one directly.
The purpose of interfaces and abstract classes is to describe the behaviour of some concrete class that implements the interface or extends the abstract class.
A class that implements an interface can be used by other code that only knows about the interface, which helps you to separate responsibilities, and be clear about what you want from the object. (The calling code will only know that the object can do anything specified in the interface; it will not know about any other methods it has.)
If you are using someone else's code that expects a Fooable (where that is the name of some interface), you are not really being asked for an object of some Fooable class (because there isn't really such a class). You are only being asked for an instance of some class that implements Fooable, i.e. which declares that it can do all the things in that interface. In short, something that "can be Foo'd".
You write a class that derives from the abstract class or implements the interface, and then instantiate that.
What you know is correct. You cannot create an object of abstract class or interface since they are incomplete class (interface is not even considered as a class.)
What you can do is to implement a subclass of abstract class which, of course, must not be abstract. For interface, you must create a class which implement the interface and implement bodies of interface methods.
Here are orginal tutorial on oracle site, http://download.oracle.com/javase/tutorial/java/IandI/abstract.html and http://download.oracle.com/javase/tutorial/java/concepts/interface.html
You can not instantiate the abstract class or an interface, but you can instantiate one of their subclasses/implementers.
You can't instantiate an abstract class or an interface, you can only instantiate one of their derived classes.
In your example
MyAbstractClass ABC = new MyAbstractClass("name") {
};
You are instantiating any class that implements Suprising.
public abstract class AbstractClass { ... }
public interface InterfaceClass { ... }
// This is the concrete class that extends the abstract class above and
// implements the interface above. You will have to make sure that you implement
// any abstract methods from the AbstractClass and implement all method definitions
// from the InterfaceClass
public class Foo extends AbstractClass implements InterfaceClass { ... }
NO, we can't create object out of an interface or Abstract class because
Main intention of creating an object is to utilize the wrapped methods and data.
As interface don't have any concrete implementation hence we cannot.
For abstract class we may have concrete method or abstract method or both.
There is no way for the API developer to restrict the use of the method thats don't have implementation.
Hope help.
No, you are not creating the instance of your abstract class here. Rather you are creating an instance of an anonymous subclass of your abstract class. And then you are invoking the method on your abstract class reference pointing to subclass object.
I've been fighting with trying to override a method in a generic abstract class.
public abstract class Grandparent<T extends Grandparent>
public T set(final T other) //does stuff I don't want to do
public abstract class Parent<T extends Parent<T>> extends Grandparent<T>
public T set(final Parent<?> other) // does stuff I want to do
All the child classes extend Parent<child>.
However, I can't call the set() function I want by just constructing one of the child classes.
Child_1 test = new Child_1();
Child_1 test_2 = new Child_1();
test.set(test_2) //this calls the function I don't want
Parent<Child_1> test_3 = new Child_1();
Parent<Child_1> test_4 = new Child_1();
test3.set(test_4) //this calls the function I do want
This requires modification of already-existing code, however. A lot of it. I don't want to rewrite the set method to
public T set(T other)
because then I'll lose the ability to set one child class object from a different child class object.
How can I write the set() method to trigger any time a child object calls it, passing in any other child object, without any modifications to outside code?
To override a method, you need provide an override-equivalent signature, which implies that the method name and number and types of arguments must be equal. This is not the case For Grandparent.set() and Parent.set(). Consequently, Parent.set() overloads, rather than overrides, Grandparent.set().
The simplest solution I see is to generalize the method signatures as follows:
public abstract class Grandparent<T extends Grandparent>
public T set(Grandparent<?> other)
public abstract class Parent<T extends Parent<T>> extends Grandparent<T>
public T set(Grandparent<?> other)
That way, the methods override, and you don't have to modify any child classes.
Subsequent comments helped to clarify what you are after, but I may still be baffled. Perhaps this will help; if not, please try to elaborate on your question.
public abstract class Grandparent<T extends Grandparent<T, Q>, Q extends Grandparent<T, Q>>
{
public abstract Q set(Q other);
}
class Parent<T extends Parent<T>>
extends Grandparent<T, Parent<T>>
{
#Override
public Parent<T> set(Parent<T> other)
{
throw new UnsupportedOperationException("set");
}
}
How can I write the set() method to
trigger any time a child object calls
it, passing in any other child object,
without any modifications to outside
code?
Can you include code modeling what you want to do - I just want to be clear what it is you want because at the moment I suspect it simply is not allowed - no matter what you do.
EDIT
Classes I used to test with...
package test.stack.overflow;
public abstract class GrandParent<T extends GrandParent>
{
public T set(final GrandParent<?> other)
{
System.out.println("GrandParent.set=" + other);
return null;
}
}
public abstract class Parent<T extends Parent<T>> extends GrandParent<T>
{
public Parent<?> set(final Parent<?> other)
{
System.out.println("Parent.set=" + other);
return other;
}
}
public class Child_1 extends Parent<Child_1>
{
}
public class Child_2 extends Parent<Child_2>
{
}
public class TestPeerage
{
public static void main(String[] args)
{
Child_1 c1 = new Child_1();
c1.set(new Child_2());
c1.set(new Child_1());
Parent<Child_1> pc1 = new Child_1();
pc1.set(new Child_2());
pc1.set(new Child_1());
}
}