Here is my scenario:
public interface Father{ public void sayHi(); }
public abstract class FatherImpl implements Father{
#Override
public void sayHi() { System.out.print("Hi"); } }
then is the child
public interface Child{}
public class ChildImpl extends FatherImpl implements Child{}
and test function is
Child c = new ChildImpl();
c.sayHi();
This will throw compiling error.
Only when i change child interface to
public interface Child{} extends Father
Then the program runs properly.
Anyone can help me explain the reason.
Child c = new ChildImpl();
The Child interface doesn't have a sayHi() method, that's in ChildImpl. You're referencing c as a Child object, so you can't access the method.
You could either reference the object as a ChildImpl or add another class.
ChildImpl c = new ChildImpl();
Or
public abstract class TalkingChild {
#Override
public void sayHi() {
System.out.print("Hi");
}
}
Or
public interface TalkingChild {
public void sayHi();
}
The best solution completely depends on your specific scenario.
The problem is that the compiler cares only the declared type - the type that is assigned is irrelevant.
Applying this to your case, the type Child has no methods. It doesn't consider that you assigned a ChildImpl, which does have a sayHi() method, to the Child variable.
Related
interface A{
public void get();
public void set();
}
abstract class abstractA implements A{
#Override
public void get(){
System.out.println("in get funciton");
}
abstract public void set();
}
class B extends abstractA implements A{
#Override
public void set(){
System.out.println("In set method");
}
}
Is it not necessary to implement get method in class B?
Is it because abstractA already implemented the same method ?
Is this multiple inheritance ?
Is it not necessary to implement get method in class B?
No, since abstractA already implements it and B extends abstractA.
Is it because abstractA already implemented the same method ?
Yes. And because B extends abstractA. Both are required for this to work.
Is this multiple inheritance ?
No, it is not. B is still inheriting only one class - abstractA.
No because get() is already implemented in abstractA. This is inheritance.
Java does not allow multiple inheritance (which consist in inheriting from multiple classes BTW). The class B inherits from abstractA, and implements the behavior required by A. Actually, you could write your code like this :
interface A{
public void get();
public void set();
}
abstract class abstractA implements A{
#Override
public void get(){
System.out.println("in get funciton");
}
abstract public void set();
}
class B extends abstractA /* no need to specify that B implements A */{
#Override
public void set(){
System.out.println("In set method");
}
}
B inherits everything implemented by abstractA, which also include its interfaces.
B inherits the implementation of get() from abstractA.
Multiple inheritance is when B inherits from more than one classes. Which is not the case here.
what is the difference between creating an Object of interface and implementing an interface
example :
public interface A{
public void testMethod();
}
on way is creating an object of interface
public class B{
A a = new A(){
#override
public void testMethod(){ //implemtation here }
};
}
other way is
public class B implements A
{
#override
public void testMethod(){}
}
You are wrong:
here you anonymously implement interface and you alrady have instance of annonymouse class
public class B{
A a = new A(){
#override
public void testMethod(){ //implemtation here }
};
}
Here you create named implementation, you only create class without instantiate it.
public class B implements A
{
#override
public void testMethod(){}
}
You can't create an object of interface. Interface it's an abstract class but with all the methods are abstract. In the first code you are creating an anonymous class (i recommend you to read about this feature in java) that implements the interface A, in this case you are limited with the interface's methods even if you define additional method in your implementation you can't call it. In the second code you are creating a class that implements the interface A which means that you have a class that at least contain all the methods defined in the interface A and you can add inside your class B other methods and call its.
It is possible to narrow return type in overriding methods in Java.
But is it possible to force this narrowing during declaration?
For example, this may be good in the pattern, where inner class is subclassed simultaneously with outer one:
public class Try_ForceNarrow {
public interface IMember {
}
public interface Container<M extends IMember> {
M createMember();
}
public static class A implements Container<A.Member> {
#Override
public Member createMember() {
return new Member();
}
public class Member implements IMember {
}
}
public static class B extends A implements Container<B.Member> {
#Override
public Member createMember() {
return new Member();
}
public class Member extends A.Member {
}
}
public static void main(String[] args) {
}
}
This code fails compile with an error of "The interface Container cannot be implemented more than once with different arguments".
How to avoid this?
Of course, I can just write
public static class B extends A {
#Override
public Member createMember() {
return new Member();
}
public class Member extends A.Member {
}
}
But this way I can forget to override createMember() and violate the pattern.
And what about A<T> implements Container<T> ? You can restrict T further as you wanted...
It appears to me that you want each subclass C to have a createMember factory method that returns a new object that has the same type. The problem is that if C1 provides a factory method that returns C1, and then C2 extends C1, there's no way to force C2 to provide its own method--it could just inherit the one from C1.
I don't think there's a solution that will catch errors at compile time, but maybe you can do something that catches the error at run time:
abstract class MemberBase {
protected abstract MemberBase doCreateMember();
protected abstract Class<?> memberClass();
public MemberBase createMember() {
MemberBase result = doCreateMember();
if (result.getClass() != memberClass()) {
throw new RuntimeException("createMember returned the wrong class");
}
return result;
}
}
public static class A extends MemberBase {
#Override
protected Member doCreateMember() {
return new Member();
}
#Override
protected Class<?> memberClass() {
return Member.class;
}
public class Member implements IMember {
}
}
public static class B extends A {
// If you forget to define this, the doCreateMember in A will be
// inherited, but it will return the wrong class and lead to a
// run-time exception
#Override
protected Member doCreateMember() {
return new Member();
}
#Override
protected Class<?> memberClass() {
return Member.class;
}
public class Member extends A.Member {
}
}
I haven't tested this, and I'm not sure it accomplishes what you are looking for. Plus I may have gotten some syntax wrong. But maybe this, or a modification of it, might be useful.
I believe this fulfills what you are trying to do.
You can create a new abstract class that implements Container which allows you to continually extend or narrow the generics, but you need to declare each class static:
class Try_ForceNarrow {
public interface IMember {
}
public interface Container<M extends IMember> {
M createMember();
}
//The abstract class that lets you continually extend or "narrow"
public static abstract class A<E extends A.Member> implements Container<E> {
public static class Member implements IMember {
}
}
//Here is the first class that extends the Abstract Class A
public static class B extends A<B.Member> { //This class now Implements Container<B.Member>
#Override
public Member createMember() {
return new Member();
}
//Since this is the first extension we will extend A.Member
public static class Member extends A.Member {
}
}
//This is an additional class that extends A but we want to extend the functionality of B.Member also.
public static class C extends A<C.Member> { //This class now Implements Container<C.Member>
#Override
public Member createMember() {
return new Member();
}
//C.Member properly extends B.Member
//if this class is going to be extended this needs to be static
public class Member extends B.Member {
}
}
}
And of course per your requirements if you remove
#Override
public Member createMember() {
return new Member();
}
From the extending sub-classes you get a compile error.
Of course it will fail, your class A implements Container<A.Member>, but your class B extends A but also implements Container<B.Member> which is like class B extends A implements Container<A.Member> Container<B.Memeber> , and in terms of the compiler, there is no difference between Container<A.Member> and Container<B.Member> due to type erasure, after compilation, all generics information will be lost, so there is no <……> after type erasure, only their upper bounds and lower bounds exist, your type parameters are unbounded so they will erase to the same type, after erasure, your class B literally looks like this class B extends A implements Container Container which is fundamentally wrong. You can narrow the return type on overrides which is called covariant return type, this will also create a bridge method in the VM to preserve porlymorphism in Generics.
Class A implements interface I that requires method doAction(). If I call a method from class A of class B, and pass "this"(class A) into that method, how can I call a method that lives in class A from the method in class B? For example:
class A implements I {
public void start() {
B.myMethod(this);
}
#Override
public void doAction() {
// Do stuff...
}
}
Class B {
public void myMehtod(Class theClass) { //How would I accept 'this', and...
theClass.doAction(); //How would I call the method?
}
}
I am doing this for purposes of a custom library, without knowing the exact name of the class that extends I.
This is a very basic question about how interfaces work. I'd recommend trying to find a tutorial about them.
Anyway, all you have to do is declare a parameter with the interface as its type. You can invoke interface methods on variables of the interface type (or any sub interface or class that implements that interface).
Class B {
public void myMethod(I theClass) {
theClass.doAction();
}
}
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}