Abstract Classes and Interfaces Java - java

Class A
public abstract class AbstractA {
public abstract void method1(int a);
public void method2() {
System.out.println("method2");
} // end method2
public abstract void method3();
}
Class B
public abstract class AbstractB {
public abstract void method3();
public abstract void method4();
}
Class C
public interface InterfaceC {
void method1(int a, int b);
void method2();
void method4();
}
Test
public abstract class Choice3 extends AbstractA implements InterfaceC {
public void method1(int a) {}
public void method4() {}
} // end class
I'm very confused as to why Choice 3 actually compiles. It does overload method1(int a), but doesn't actually overload method1(inta intb).

public abstract class Choice3 extends AbstractA implements InterfaceC
when your class iself is abstract it need not to implement all methods of its direct/indirect abstract parent

Related

Optional overloaded methods when overriding

Case :
I have an abstract class A. It contains two methods
abstract void search(Position p);
abstract void search(Animal a);
Class B and C extends A. I would like class B to implement search(Position p) only and class C to implement search(Animal a) only. However when I do so it gives an error, telling me to implement both of the method overloads.
How could I solve the problem? Any help is greatly appreciated
Here are the rules for classes extending Abstract class
First concrete/non-abstract class must implement all methods
If abstract class extends Abstract class, it can but need not implement
abstract methods.
Option 1: Interface Segregation
separate search(XXX) into two abstract classes
Option 2: Generics. Make search a Generic Type
public abstract class ClassA {
public abstract <T> void search(T t);
public static void main(String ...args){
ClassA classA = new ClassB();
classA.search(new Animal());
}
}
class Animal{
}
class ClassB extends ClassA {
#Override
public <Animal> void search(Animal t) {
System.out.println("called");
}
}
Option 3: Interface
public class ClassA {
public static void main(String... args) {
Searchable classA = new ClassB();
classA.search(new Animal());
}
}
interface Searchable {
public <T> void search(T t);
}
class Animal {
}
class ClassB implements Searchable {
#Override
public <Animal> void search(Animal t) {
System.out.println("called");
}
}
Option 4: Throw UnsupportedOperationException Exception(Not recomended)
class ClassB extends ClassA {
#Override
void search(Position p) {
throw new UnsupportedOperationException("Not Supported");
}
#Override
void search(Animal a) {
}
}

In multiple inheritance between abstract class and interface

In case of multiple inheritance with abstract class and interface. Abstract class dance() is called.why is the priority given to abstract class method but not default method in interface.
public class Child extends Absclass implements Interfc{
public static void main(String[] args){
Child c = new Child();
c.dance();
}
}
Abstract class Absclass{
public void dance(){
System.out.println("abstract dancing");
}
}
Interface Interfc{
default public void dance(){
System.out.println("interface dancing");
}
}

Dynamically cast classes

I'm trying to do something along the lines:
abstract class Base {}
public interface One {...}
public interface Two {...}
public class A extends Base implements One {...}
public class B extends Base implements One, Two {...}
public class C extends Base implements Two {...}
public class Container
{
class Handler
{
public void doSomething(A obj){System.out.println("A");}
public void doSomething(B obj){System.out.printLn("B");}
public void doSomething(C obj){System.out.println("C");}
}
Base base;
Handler handler;
public Container(Base base)
{
this.base = base;
this.handler=new Handler();
}
public void set(Base base)
{
this.base=base;
}
public void go()
{
this.handler.doSomething(this.base);
}
}
Container con=new Container(new A());
con.go();
con.set(new B());
con.go();
Where the output would end up being "A" "B", but I'm running into problems dynamically casting Container.base to the appropriate class;
The closest solution I have found is in the Container.go function add in an if else chain checking the instanceOf the class and casting the parameter to the corresponding class then calling handler.doSomething in each if block.
public void go()
{
if(this.base instanceOf A)
{
this.handler.doSomething((A)this.base);
}
else if(this.base instanceOf B)
....
}
Is there a better way to go about this?
Which method is called is determined at compile time and not at run time so dynamic casting isn't going to work without some reflection or other tinkering about. I would suggest a better approach is to move the logic for
public void doSomething(A obj){System.out.println("A");}
public void doSomething(B obj){System.out.printLn("B");}
public void doSomething(C obj){System.out.println("C");}
Into the the specific classes. For example:
abstract class Base {
absract public void doSomething();
}
public class A extends Base implements One {
public void doSomething() {System.out.printLn("A");}
}
...
class Handler {
public void doSomething(Base obj){obj.doSomething();}
}
Now your handler doesn't need to care about the specific class of a Base object it is getting.
You could use the visitor pattern:
public interface Visitor {
public void doSomething(A obj);
public void doSomething(B obj);
public void doSomething(C obj);
}
Declare an abstract method in Base (or in a new interface):
abstract class Base {
public abstract void accept(Visitor v);
}
and implement it in A, B, C:
public class A extends Base implements One {
#Override
public void accept(Visitor v) {
v.doSomething(this);
}
...
}
public class B extends Base implements One, Two {
#Override
public void accept(Visitor v) {
v.doSomething(this);
}
...
}
public class C extends Base implements Two {
#Override
public void accept(Visitor v) {
v.doSomething(this);
}
...
}
Handler implements Visitor:
class Handler implements Visitor {
#Override
public void doSomething(A obj){
System.out.println("A");
}
#Override
public void doSomething(B obj){
System.out.printLn("B");
}
#Override
public void doSomething(C obj){
System.out.println("C");
}
}
And finally, go becomes:
public void go() {
this.base.visit(this.handler);
}
UPDATE
Note that #Evan Jones' solution is simpler and it could be what you need. The visitor pattern is used when you want to separate the implementations of the doSomething methods from the A, B, C classes and/or you want the ability to add new operations without changing these classes.

Java Generics - Bounded Type Parameters

Let me describe my intention with an example,
class Base {
public void sayHi() {
System.out.println("Hi");
}
}
class ChildOne extends Base {
public void sayBye() {
System.out.println("Bye-1");
}
}
class ChildTwo extends Base {
public void sayBye() {
System.out.println("Bye-2");
}
}
public class MainClass {
public static <T extends Base> void genericFunction(T child) {
child.sayBye();
}
public static void main(String[] args) {
ChildOne childOne = new ChildOne();
ChildTwo childTwo = new ChildTwo();
genericFunction(childOne);
genericFunction(childTwo);
}
}
This code is wrong. But my intention is the child class (some already existing classes in a project) which has similar properties between them are they extend the base class and have sayBye() member function.
Is there a way to pass all the child classes as parameter to a generic function and to call the member function sayBye() (as per this example)?
Sure, you can either create a common base class or common interface for all the classes that have a sayBye method.
Then you can change the type bound of your generic type parameter:
public static <T extends CommonInterface> void genericFunction(T child) {
child.sayBye();
}
or without generics:
public static void nonGenericFunction(CommonInterface child) {
child.sayBye();
}
You can bring common functionality together without adjusting the hierarchy by introducing an interface that defines it and creating empty classes extending the common objects.
class Base {
public void sayHi() {
System.out.println("Hi");
}
}
class ChildOne extends Base {
public void sayBye() {
System.out.println("Bye-1");
}
}
class ChildTwo extends Base {
public void sayBye() {
System.out.println("Bye-2");
}
}
// The common functionality I want to use.
interface Bye {
public void sayBye();
}
class ChildOneBye extends ChildOne implements Bye {
// Don't need anything here.
}
class ChildTwoBye extends ChildTwo implements Bye {
// Don't need anything here.
}
public static <T extends Bye> void genericFunction(T child) {
child.sayBye();
}
public void test(String[] args) {
Bye childOne = new ChildOneBye();
Bye childTwo = new ChildTwoBye();
genericFunction(childOne);
genericFunction(childTwo);
}
One way is to mark the base class as abstract and have an abstract method sayBye(). In this way you don't need to change anything else in your codebase.
abstract class Base {
public void sayHi() {
System.out.println("Hi");
}
public abstract void sayBye();
}
Another approach is to use interface ByeInterface and use it to call sayBye(). Here is the with the required changes.
interface ByeInterface {
void sayBye();
}
class Base {
public void sayHi() {
System.out.println("Hi");
}
}
class ChildOne extends Base implements ByeInterface {
public void sayBye() {
System.out.println("Bye-1");
}
}
class ChildTwo extends Base implements ByeInterface {
public void sayBye() {
System.out.println("Bye-2");
}
}
public class MainClass {
public static <T extends ByeInterface> void genericFunction(T child) {
child.sayBye();
}
public static void main(String[] args) {
ChildOne childOne = new ChildOne();
ChildTwo childTwo = new ChildTwo();
genericFunction(childOne);
genericFunction(childTwo);
}
}
This approach can be used if you can not mark your base class as abstract class. Using interface, you can even call it without using generic.
public static void nonGenericFunction(ByeInterface child) {
child.sayBye();
}

Can a normal Class implement multiple interfaces?

I know that multiple inheritances between Interfaces is possible, e.g.:
public interface C extends A,B {...} //Where A, B and C are Interfaces
But is it possible to have a regular Class inherit from multiple Interfaces like this:
public class A implements C,D {...} //Where A is a Class and C and D are interfaces
A Java class can only extend one parent class. Multiple inheritance (extends) is not allowed. Interfaces are not classes, however, and a class can implement more than one interface.
The parent interfaces are declared in a comma-separated list, after the implements keyword.
In conclusion, yes, it is possible to do:
public class A implements C,D {...}
In a word - yes.
Actually, many classes in the JDK implement multiple interfaces. E.g., ArrayList implements List, RandomAccess, Cloneable, and Serializable.
public class A implements C,D {...} valid
this is the way to implement multiple inheritence in java
Yes, a class can implement multiple interfaces. Each interface provides contract for some sort of behavior. I am attaching a detailed class diagram and shell interfaces and classes.
Ceremonial example:
public interface Mammal {
void move();
boolean possessIntelligence();
}
public interface Animal extends Mammal {
void liveInJungle();
}
public interface Human extends Mammal, TwoLeggedMammal, Omnivore, Hunter {
void liveInCivilization();
}
public interface Carnivore {
void eatMeat();
}
public interface Herbivore {
void eatPlant();
}
public interface Omnivore extends Carnivore, Herbivore {
void eatBothMeatAndPlant();
}
public interface FourLeggedMammal {
void moveWithFourLegs();
}
public interface TwoLeggedMammal {
void moveWithTwoLegs();
}
public interface Hunter {
void huntForFood();
}
public class Kangaroo implements Animal, Herbivore, TwoLeggedMammal {
#Override
public void liveInJungle() {
System.out.println("I live in Outback country");
}
#Override
public void move() {
moveWithTwoLegs();
}
#Override
public void moveWithTwoLegs() {
System.out.println("I like to jump");
}
#Override
public void eat() {
eatPlant();
}
#Override
public void eatPlant() {
System.out.println("I like this grass");
}
#Override
public boolean possessIntelligence() {
return false;
}
}
public class Lion implements Animal, FourLeggedMammal, Hunter, Carnivore {
#Override
public void liveInJungle() {
System.out.println("I am king of the jungle!");
}
#Override
public void move() {
moveWithFourLegs();
}
#Override
public void moveWithFourLegs() {
System.out.println("I like to run sometimes.");
}
#Override
public void eat() {
eatMeat();
}
#Override
public void eatMeat() {
System.out.println("I like deer meat");
}
#Override
public boolean possessIntelligence() {
return false;
}
#Override
public void huntForFood() {
System.out.println("My females hunt often");
}
}
public class Teacher implements Human {
#Override
public void liveInCivilization() {
System.out.println("I live in an apartment");
}
#Override
public void moveWithTwoLegs() {
System.out.println("I wear shoes and walk with two legs one in front of the other");
}
#Override
public void move() {
moveWithTwoLegs();
}
#Override
public boolean possessIntelligence() {
return true;
}
#Override
public void huntForFood() {
System.out.println("My ancestors used to but now I mostly rely on cattle");
}
#Override
public void eat() {
eatBothMeatAndPlant();
}
#Override
public void eatBothMeatAndPlant() {
eatPlant();
eatMeat();
}
#Override
public void eatMeat() {
System.out.println("I like this bacon");
}
#Override
public void eatPlant() {
System.out.println("I like this broccoli");
}
}
Of course... Almost all classes implements several interfaces. On any page of java documentation on Oracle you have a subsection named "All implemented interfaces".
Here an example of the Date class.
It is true that a java class can implement multiple interfaces at the same time, but there is a catch here.
If in a class, you are trying to implement two java interfaces, which contains methods with same signature but diffrent return type, in that case you will get compilation error.
interface One
{
int m1();
}
interface Two
{
float m1();
}
public class MyClass implements One, Two{
int m1() {}
float m1() {}
public static void main(String... args) {
}
}
output :
prog.java:14: error: method m1() is already defined in class MyClass
public float m1() {}
^
prog.java:11: error: MyClass is not abstract and does not override abstract method m1() in Two
public class MyClass implements One, Two{
^
prog.java:13: error: m1() in MyClass cannot implement m1() in Two
public int m1() {}
^
return type int is not compatible with float
3 errors
Yes, it is possible. This is the catch: java does not support multiple inheritance, i.e. class cannot extend more than one class. However class can implement multiple interfaces.
An interface can extend other interfaces. Also an interface cannot implement any other interface.
When it comes to a class, it can extend one other class and implement any number of interfaces.
class A extends B implements C,D{...}

Categories

Resources