If you have a base class that is in a jar file that looks like:
public class A {
public void awesome(int i){
}
}
...which is extended by these classes (also in a jar) as follows:
public class A1 extends A {
#Override
public void awesome(int i){
}
}
and
public class A2 extends A {
#Override
public void awesome(int i){
}
}
...is it possible to override the base function in a generic way?
Say there is an implementation that was being added via anonymous inner class - can you code that such that the entire anonymous inner implementation only appears once?
So instead of:
public class Test {
public static void main(String args[]){
A1 mySpecialA1 = new A1(){
#Override
public void awesome(int i){
//awesome implementation
}
};
A2 mySpecialA2 = new A2(){
#Override
public void awesome(int i){
//awesome implementation
}
};
}
}
...you could have (this is where it breaks down):
public class SpecialAFactory {
public static <T extends A> getSpecialA(){
return new T(){
#Override
public void awesome(int i){
//only once
}
};
}
}
So ultimately you would be passing in the subclass that you want to get a new anonymous instance of.
Although you cannot do it with generics, there is a simple, easy to understand, solution that lets you avoid code duplication in cases like that:
public class Test {
public static void main(String args[]){
A1 mySpecialA1 = new A1(){
#Override
public void awesome(int i){
awesomeImplementation(i);
}
};
A2 mySpecialA2 = new A2(){
#Override
public void awesome(int i){
awesomeImplementation(i);
}
};
}
private static void awesomeImplementation(int i) {
//awesome implementation
}
}
Related
interface Y {
void search(String name);
}
class A implements Y {
void search(String name) {
//Is it possible to say: "If I was called from class B then do a search("B");
}
}
class B extends A {
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
Given the above code is it possible to reason in superclass which subclass was used for calling a method?
The reason I want to do this is because the code in Search is very similar for all Subclasses, the only thing that changes is the Classname, so I thought there is no need to Override in each subclass. I have updated the code to reflect this. Please let me know if there is a better way of doing it/
Calling this.getClass() inside your search method will give you the concrete class of the current instance.
For example:
class Example
{
static class A {
public void search() {
System.out.println(getClass());
}
}
static class B extends A {}
public static void main (String[] args) throws java.lang.Exception
{
new A().search();
new B().search();
}
}
outputs
class Example$A
class Example$B
The cleanest way to do it is to override the method in each subclass.
interface Y {
void search();
}
class A implements Y {
public void search(){
search("A");
}
protected void search(String name) {
// implement your searching algoithm here
}
}
class B extends A {
public void search(){
search("B");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
That's the way inheritance is suppose to works. A super class should not know its subclasses.
And, in case you extends your class B, you can easily either:
-Keep the same behaviour as B:
class C extends B {
// do nothing, when calling search, it calls the method implemented in B
}
-Change the behaviour to search for "C"
class C extends B {
public void search(){
search("C"); // or search("whateveryouwant")
}
}
You can simply override the method in class B.
The other way could be to write the search() method as
void search() {
if (this.getClass().equals(B.class)) {
//The logic for B
} else if (this.getClass().equals(A.class)) {
//The logic for A
}
}
You have to provide the fully qualified name for the class.
Better follow template pattern.
interface Y {
void search(String name);
}
abstract class AbstractionTemplate implements Y{
#Override
public void search(String name) {
//a lot of code.
System.out.println("common stuff start");
doImplspecificStuffOnly();
System.out.println("common stuff end");
//a lot of code.
}
abstract void doImplspecificStuffOnly();
}
class A extends AbstractionTemplate{
#Override
void doImplspecificStuffOnly() {
System.out.println("a's stuff");
}
}
class B extends A {
#Override
void doImplspecificStuffOnly() {
System.out.println("B's stuff");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search("hey");
}
}
I have few classes that implements some interface. Now I want to create new class, which can extend one of them, based on runtime calculation while using interfaces methods. Let's talk in code:
public interface Interface {
public void doSomething();
}
public class A implements Interface {
#Override
public void doSomething() {
System.out.println("hello");
}
}
public class B implements Interface {
#Override
public void doSomething() {
System.out.println("hi");
}
}
These are existing classes, so now I need to do something like this (which is not working of course):
public class C<T extends Interface> extends T {
public void doSomethingElse() {
this.doSomething();
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C<A>();
} else {
c = new C<B>();
}
c.doSomethingElse();
}
}
Is it possible somehow, except the way that I pass argument Interface other to C's constructor and store to class property..?
A class cannot extend from its type parameter.
Use composition instead of inheritance:
public class C<T extends Interface> {
private final T foo;
public C(T foo){
this.foo = foo;
}
public void doSomethingElse() {
foo.doSomething();
}
public static void main(String[] args) {
C<?> c;
if(isSomethingLoaded) {
c = new C<>(new A());
} else {
c = new C<>(new B());
}
c.doSomethingElse();
}
}
You might even not need the type parameter here, but just use the interface type as argument/ member type.
I think it's situations like this which show why we have the rule of favouring composition over inheritance. Consider this solution using composition:
public class Test {
public interface Interface {
void doSomething();
}
public static class A implements Interface {
#Override
public void doSomething() {
System.out.println("Doing A");
}
}
public static class B implements Interface {
#Override
public void doSomething() {
System.out.println("Doing B");
}
}
public static class C implements Interface {
private Interface composedWith;
public C(Interface i) {
this.composedWith = i;
}
#Override
public void doSomething() {
this.composedWith.doSomething();
}
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C(new A());
} else {
c = new C(new B());
}
c.doSomething();
}
}
Personally, I feel this is a clearer and move flexible way of achieving what you are trying to do.
I am working on a system which requires performance at its peak and i am stuck in one scenario whose solution i want to ask.
Here is my code
public interface ILoad {
public void loadData();
}
public class ClassOne implements ILoad {
#Override
public void loadData() {
System.out.println("CLASS ONE LOADING DATA ");
}
}
public class ClassTwo implements ILoad {
#Override
public void loadData() {
System.out.println("CLASS TWO LOADING DATA");
}
}
public static void main(String[] args) {
load(new ClassOne());
load(new ClassTwo());
}
public static void load(Object o){
ILoad ref = (ILoad) o;
ref.loadData();
}
As you can see in above case there are no if else or switch conditions all the code is executed using interfaces by reference which is super fast when it comes to programming.
My question is for instance my interface has two methods loadData() and loadRecord()
Now if I want to execute these two methods just as on above example how can I do this? one way is make a separate class, second way reflection and introspection. Are there any better solutions?
You are not using polymorphism properly if you have to cast.
How about something like this?
public static interface ILoadData {
public void loadData();
}
public static interface ILoadRecord {
public void loadRecord();
}
public static interface ILoadEither extends ILoadData, ILoadRecord {
}
public static class ClassOne implements ILoadData {
#Override
public void loadData() {
System.out.println("CLASS ONE LOADING DATA ");
}
}
public static class ClassTwo implements ILoadData {
#Override
public void loadData() {
System.out.println("CLASS TWO LOADING DATA");
}
}
public static class ClassThree implements ILoadRecord {
#Override
public void loadRecord() {
System.out.println("CLASS THREE LOADING RECORD");
}
}
public static class ClassFour implements ILoadRecord, ILoadData {
#Override
public void loadRecord() {
System.out.println("CLASS FOUR LOADING RECORD");
}
#Override
public void loadData() {
System.out.println("CLASS FOUR LOADING DATA");
}
}
public static class ClassFive implements ILoadEither {
#Override
public void loadRecord() {
System.out.println("CLASS FIVE LOADING RECORD");
}
#Override
public void loadData() {
System.out.println("CLASS FIVE LOADING DATA");
}
}
public static void load(ILoadData o) {
o.loadData();
}
public static void load(ILoadRecord o) {
o.loadRecord();
}
public static void load(ILoadEither o) {
o.loadRecord();
}
public static void main(String[] args) {
load(new ClassOne());
load(new ClassTwo());
load(new ClassThree());
load((ILoadData)new ClassFour());
load((ILoadRecord)new ClassFour());
load(new ClassFive());
}
Here we have multiple static load methods, each taking a parameter of a different interface but the compiler can decide at compile time which to use, unless it is ambiguous, in which case you need some other trick - I use casting here as it is simple but you would be better to use an adaptor of some sort.
Why aren't you doing this:
public static void load(ILoad o){ // both classes implement Iload. using Object here gives a chance for anything to come here.
o.loadData();
}
I'm not sure if I've understood your question, but isn't enough the following code?
public interface ILoad {
public void loadData();
public void loadRecord();
}
public class ClassOne implements ILoad{
#Override
public void loadData() {
System.out.println("CLASS ONE LOADING DATA ");
}
#Override
public void loadRecord() {
System.out.println("CLASS ONE LOADING RECORD");
}
}
public class ClassTwo implements ILoad{
#Override
public void loadData() {
System.out.println("CLASS TWO LOADING DATA ");
}
#Override
public void loadRecord() {
System.out.println("CLASS TWO LOADING RECORD");
}
}
public static void main(String[] args) {
// TODO code application logic here
load(new ClassOne());
load(new ClassTwo());
//new objects created here, instances can be created just once
loadRecord(new ClassOne());
loadRecord(new ClassTwo());
}
public static void load(ILoad l){
ref.loadData();
}
public static void loadRecord(ILoad l){
ref.loadRecord();
}
Can Someone tell me with an example why an class should be defined inside an interface.
The below is the simple code i was trying.
interface Watsapp
{
class A
{
public void Validate()
{
}
};
abstract public void SendText();
public void SendPic();
};
its totally depends on logic requirements.
whenever we declare inner class, it treats as a data member so here also you can treat this class as a data member
just assume scenario some one needs object of A inside Interface and there is no class right now.
see eg.
public interface Watsapp
{
class A
{
public void Validate()
{
}
public String iDoSomething()
{
return "i did";
}
};
public A objOfA = new A();
abstract public void SendText();
public void SendPic();
};
And main Class is bellow:
public class TestMain {
public static void main(String[] str){
System.out.println( Watsapp.objOfA.iDoSomething());
}
}
mostly people create anonymous class for one time use, but here You created a class with name.
see:
public interface Watsapp
{
/*class A
{
public void Validate()
{
}
public String iDoSomething()
{
return "i did";
}
};*/
Thread t = new Thread()
{
public void run() {
// something ...
}
};
abstract public void SendText();
public void SendPic();
};
Thank you.
I need to write some importers. They need all the same initialization. So I try to write an abstract class, which does all the initialization and also has the main method, so that all sub-classes just need to implement run() to do their specific import work:
public abstract class AbstractImporter {
public AbstractImporter() {
// Initialization
}
public abstract void run();
public static void main(String[] args) {
AbstractImporter importer = new AbstractImporter();
importer.run();
}
}
public class ConcreteClass() {
public void run() {
// Do some importing
}
}
Of course it fails to create an instance of this abstract class (new AbstractImporter()).
Does anybody has any idea how to solve that? TIA!
Obviously you need a concrete class - anonymous or otherwise.
Better to move the main method to another class and instantiate the appropriate concrete class based on data (either your domain specific or a constant) and then run it. This way each implementation can be independent of other implementations.
public abstract class AbstractImporter {
public AbstractImporter() {
// Initialization
}
public abstract void run();
}
public class ConcreteImporter1 extends AbstractImporter {
public void run() {
//do something
}
}
public class ImporterMain() {
public static void main(String[] args) {
AbstractImporter importer = createImporter(args[1]);
importer.run();
}
private static AbstractImporter createImporter(String type) {
if (type.equals("1")) {
return new ConcreteImporter1();
}
....
}
}
new AbstracterImporter() {
public void run() {
// ...
}
};
I apologize for current lack of formatting, currently on a mobile device.
public abstract class AbstractImporter {
public AbstractImporter() {
// Initialization
}
public abstract void run();
public static void main(String[] args) {
AbstractImporter importer = new AbstractImporter(){
public void run() {
System.out.println("Anonymous implementation");
}
};
importer.run();
}
}
You cannot create an instance of an abstract class.
public abstract class AbstractImporter {
public AbstractImporter() {
// Initialization
}
public abstract void run();
}
public class ConcreteClass extends AbstractImporter{
public void run(){
//Implementation
}
public static void main(String args[]){
AbstractImporter ai = new ConcreteClass();
ai.run();
}
}