I have a scenario that i want to create one support class called D which contains a generic method. I have set the upper bound for type variable.
class A{
void show(){
System.out.println("Hello A");
}
}
class B extends A{
void msg(){
System.out.println("Hello B");
}
}
class C extends A{
void msg(){
System.out.println("Hello C");
}
}
class D{
<T extends A> void display(T ob){
ob.msg(); //here i want to do some tricks
}
}
First i want to share my objective. Here msg() function of B and C class has different implementations. I want to create one support class called D that has one display method, using display method i want to call either msg() function of B or C class dependent on instantiation. Can you tell me how can i achieve it?
You need to have the method msg() in class A, otherwise the display() method in class D does not know if this method exist or not in the object that you're passing to it. (What if someone makes a class E that extends A but does not have a msg() method, and you pass an E to D.display()?).
If you don't want to implement the msg() method in class A, then you can make it abstract (and you'll also have to make the class abstract).
abstract class A {
public abstract void msg();
// ...
}
more like an architecture style, I would use an interface for that, so your generic method constrains to <T extends If> void display(T ob) where If is the interface with the abstract method msg
interface If {
void msg();
}
class A {
void show() {
System.out.println("Hello A");
}
}
class B extends A implements If {
#Override
public void msg() {
System.out.println("Hello B");
}
}
class C extends A implements If {
#Override
public void msg() {
System.out.println("Hello C");
}
}
class D {
<T extends If> void display(T ob) {
ob.msg(); // here i want to do some tricks
}
}
You don't need generics for this, there is basic concept called dynamic binding in Java.
abstract class A{
void show(){
System.out.println("Hello A");
}
abstract void msg();
}
class B extends A{
#Override
void msg(){
System.out.println("Hello B");
}
}
class C extends A{
#Override
void msg(){
System.out.println("Hello C");
}
}
class D{
void display(A ob){
ob.msg();
}
}
Here an appropriate instance provided to method will determine which class method should in called at runtime.
Related
Here's something I quite understand:
abstract class A {
public void foo() {
System.out.println("a");
}
}
abstract class B extends A {
#Override
public abstract void foo();
public void bar() {
super.foo();
foo();
}
}
class C extends B {
#Override
public void foo() {
System.out.println("c");
}
}
public static void main(String[] args) {
new C().foo();
new C().bar();
}
new C().foo() prints c to the console, while new C().bar() prints a then c.
Calling super.foo() is illegal in the #foo() implementation of the C class.
I don't have a clear question, but if anyone could give a complete explanation of what is going on with the foo method, it may be interesting I think.
A is super class for B, so calling super.foo() inside B calls method defined in A, and calling foo() inside the same class will invoke its own implementation that should be delivered by any subclass.
You cannot use super.foo() within C class because it is defined as abstract in B and cannot be invoked directly.
class Main
{
public static void main(String[] arg)
{
C c = new C();
c.show(); //how to access class A
}
}
class A
{
void show()
{
System.out.println("inside A");
}
}
class B extends A
{
void show()
{
System.out.println("inside B");
}
}
class C extends B
{
void show()
{
super.show(); //How to access class A
System.out.println("inside C");
}
}
Using super I can access Super Class variables and methods like C can access B's methods but what if I want to access A's methods in C. How do I do that in simple way like using super? Like two super should do the trick...
And how do I access Class A method only by allocating Class C(if name-hiding present)?
There is no construct in Java to do something like c.super.super.show() as it violates encapsulation. The Law of Demeter is a good principle illustrating why this is rightly avoided. Taking this into account, the way you can do what you request within Java is to expose a.show() in b like this:
class Main
{
public static void main(String[] arg)
{
C c = new C();
c.show(); //how to access class A
}
}
class A
{
void show()
{
System.out.println("inside A");
}
}
class B extends A
{
void show()
{
System.out.println("inside B");
}
void showA()
{
super.show();
}
}
class C extends B
{
void show()
{
super.showA(); // Calls A
System.out.println("inside C");
}
}
One way of using A's show() method in C is by creating class A object in C and using A's show function.
class C extends B
{
void show()
{
new A().show();
super.show();
System.out.println("inside C");
}
}
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");
}
}
so I define a interface
public interface Behavior {
public void eat();
public void sleep();}
and i define a class like this
class Son extends Father implements Behavior {
#Override
public void eat() {
System.out.println("eat");
}
#Override
public void sleep() {
System.out.println("sleep");
}
}
does it make sense that after create a variable Father father = new Son(),
using the casting like (Behavior)father, if it does, how does it work?,will it invoke the method from object Son?
Due to dynamic method binding/polymorphysm, at runtime JVM will always go for object type instead of reference type. So it will still call method of object Son.
Visualize casting an object as putting new clothes on that object. It has a different appearance but underneath whatever clothes you put on it, it's still the same object.
Following snippet will clear your doubts
class Father
{
public void getFather()
{
System.out.println("inside father ");
}
}
interface Behavior {
public void eat();
public void sleep();
}
class Son extends Father implements Behavior
{
public void eat() {
System.out.println("Son Eat");
}
public void sleep() {
System.out.println("Son slepp");
}
public void getSon()
{
System.out.println("in son class");
}
}
public class A
{
public static void main(String [] args)
{
Father f=new Son();
f.getClass() ; //only method available
Behavior beh=(Behavior)f;
beh.sleep();// methods declared in Behavior interface
beh.eat();// methods declared in Behavior interface
Son s =(Son)f;
s.getSon();//methods declared in Behavior as well as methods defined in Son are available
}
}
See also :
What class does the target object take on after casting?
specially Bill K answer
I have two interfaces:
interface A {
void foo();
}
interface B {
void bar();
}
I am able to create anonymous instances of classes implementing either of these interfaces like so:
new A() {
void foo() {}
}
or:
new B() {
void bar() {}
}
I want to create an anonymous class that implements both interfaces. Something like (the fictitious):
new A implements B {
void foo() {}
void bar() {}
}
This obviously gives a compile error: "B cannot be resolved to a type".
The workaround is quite simple:
class Aggregate implements A, B {
void foo() {}
void bar() {}
}
I then use Aggregate where ever I would have used the anonymous class.
I was wondering if it is even legal for an anonymous class to implement two interfaces.
"An anonymous inner class can extend one subclass or implement one
interface. Unlike non-anonymous classes (inner or otherwise), an anonymous
inner class cannot do both. In other words, it cannot both extend a class and
implement an interface, nor can it implement more than one interface. " (http://scjp.wikidot.com/nested-classes)
If you are determined to do this, you could declare a third interface, C:
public interface C extends A, B {
}
In this way, you can declare a single anonymous inner class, which is an implementation of C.
A complete example might look like:
public class MyClass {
public interface A {
void foo();
}
public interface B {
void bar();
}
public interface C extends A, B {
void baz();
}
public void doIt(C c) {
c.foo();
c.bar();
c.baz();
}
public static void main(String[] args) {
MyClass mc = new MyClass();
mc.doIt(new C() {
#Override
public void foo() {
System.out.println("foo()");
}
#Override
public void bar() {
System.out.println("bar()");
}
#Override
public void baz() {
System.out.println("baz()");
}
});
}
}
The output of this example is:
foo()
bar()
baz()
For save some keystrokes (for example if the interfaces have a lot of methods) you can do this:
abstract class Aggregate implements A, B {
}
new MyObject extends Aggregate {
void foo() {}
void bar() {}
}
Notice the key is to declare the Aggregate as abstract.
Note that you can make a named local class that implements the two interfaces:
void method() {
class Aggregate implements A, B {
void foo() {}
void bar() {}
}
A a = new Aggregate();
B b = new Aggregate();
}
This save you from doing a class-level or top-level class declaration.
The result is called a local class. Local classes declared in instance methods are also inner classes, which means that they can reference the containing object instance.