Here is the following code
public abstract class A {
public abstract <E> void foo(E e);
}
the subclass:
public class B extends A {
#Override
public <OtherClass> void foo(OtherClass oc) {
oc.someOtherClassMethod(); //here compiler cannot see method
}
}
and class with main
public class C {
public static void main(String[] args) {
OtherClass oc = new OtherClass();
A a = new B();
a.foo(oc);
}
}
the error I get:
error: cannot find symbol
...
symbol: method someOtherClassMethod()
location: variable oc of type OtherClass
where OtherClass is a type-variable:
OtherClass extends Object declared in method <OtherClass>write(OtherClass )
1 error
Why cannot I use the someOtherClassMethod()? Without generics everything works, but I would like to be able to extend other classes in which I override foo() method
Solution:
public abstract class A <E> {
public abstract void foo(E e);
}
Subclass:
public class B extends A<OtherClass> {
#Override
public void foo(OtherClass oc) {
oc.someOtherClassMethod();
}
}
However, now I need use in main function:
A<OtherClass> a = new B();
try
public abstract class A<E> {
public abstract void foo(E e);
}
and
public class B extends A<OtherClass>
Related
I need to have two methods, one that receives an extension of an abstract class (A) and another that extends this same class and extends an interface (B), like follows:
public class MyClass {
public static void main(String args[]) {
method(new C());
}
public static <T extends A & B> void method(T t) {
// some method
}
public static void method(A a) {
// some method
}
abstract static class A{
}
interface B{
}
static class C extends A{
}
static class D extends A implements B{
}
}
However I'm getting an error saying that they clash
/MyClass.java:10: error: name clash: method(A) and <T>method(T) have the same erasure
public static void method(A a) {
^
where T is a type-variable:
T extends A,B declared in method <T>method(T)
Do anyone knows a work around and what is the reason of this behavior?
public class superA {
public void display() {
System.out.println("In super class superA");
}
}
public class subB extends superA {
#Override
public void display() {
System.out.println("In sub class subB");
}
}
public class subC extends superA {
#Override
public void display() {
System.out.println("In sub class subC");
}
}
If an object of sub class subB calls display method, it should give output like:
(new line)In super class superA
(new line)In sub class subB
The method names of all the classes parent and child is same, when you want to override superclass/parent class method with same name in child class you have to use super keyword.
public class superA {
public void display() {
System.out.println("\nIn super class superA");
}
}
public class subB extends superA {
#Override
public void display() {
super.display();
System.out.println("\nIn sub class subB");
}
}
public class subC extends superA {
#Override
public void display() {
super.display();
System.out.println("\nIn sub class subC");
}
}
How to use a non-abstract method from an abstract class in another class without extending?
Abstract Class:
package com.test;
public abstract class MyAbstract {
public abstract void abstractMethod();
public void callNonAbstractMethod() {
System.out.println("Hello");
}
}
The anonymous class:
package com.test;
public class Example {
public static void main(String[] args) {
new Example().something();
}
void something() {
MyAbstract a = new MyAbstract() {
#Override
public void abstractMethod() {
//TODO implement
}
};
a.callNonAbstractMethod();
}
}
Internal class generated by the compiler would be for above example.
static class Example extends MyAbstract
{
Example(){}
void abstractMethod()
{
System.out.println("hiee");
}
}
Abstract Class:
package com.test;
public abstract class MyAbstract {
public abstract void abstractMethod();
public void callNonAbstractMethod() {
System.out.println("Hello");
}
}
You can't.
To call any non-static method of some class A, you need an instance of A or of a subclass of A, as such a method typically operates on data within such an instance. That's at the very core of what "object-oriented" is all about.
In your case, A is abstract and can't have direct instances. So the only way to call your method is to have some instance of some class B that extends A. You can either find an existing subclass that you can use, or create your own subclass.
I think you can use an anonymous class. Although it is a kind of extension, you are not explicitly using the keyword extends. In fact, you cannot use any class in java without implicitly extending because every class extends Object.
package com.test;
public class Example {
public static void main(String[] args) {
new Example().something();
}
void something() {
MyAbstract a = new MyAbstract() {
#Override
public void abstractMethod() {
//TODO implement
}
};
a.callNonAbstractMethod();
}
}
and here's your abstract class:
package com.test;
public abstract class MyAbstract {
public abstract void abstractMethod();
public void callNonAbstractMethod() {
System.out.println("Hello");
}
}
results in:
Hello
Using the following code:
public class Animal {
public void a() {
System.out.println("Animal");
}
}
public class Cat extends Animal {
public void a() {
System.out.println("Cat");
}
}
public class BlackCat extends Cat {
public static void main(String[] args) {
BlackCat blackCat = new BlackCat();
blackCat.a();
}
}
How to use in child class BlackCat method a() from Animal but not from Cat?
I want to receive Animal in console.
I guess you could add an addition function with a set prefix (this case _) and use that as your "super accessor" or what ever you want to call it.
public class Cat extends Animal {
public void a() {
System.out.println("Cat");
}
public void _a() {
super.a();
}
}
Say you have a super-class. In that super class you want to pass runtime object of itself (this) as a parameter to an overloaded method. Trick is, this overloaded method is overloaded by sub-class type. When you try to do it, you'll get a
method ... is not applicable(actual argument
... cannot be converted to ... by method invocation
conversion)
Instead you would need to implement the method separately in each subtype (just to get the correct runtime class), which is a lot of duplicate effort when the contents of the method are identical.
e.g:
public class InferTypeTest {
public static void main(String[] args) {
SubClass1 s1 = new SubClass1();
s1.sayHi();
}
public static void sayHi(SubClass1 clz) {
System.out.println("clz 1");
}
private abstract static class SuperClass{
public void sayHi() {
InferTypeTest.sayHi(this);
}
}
private static class SubClass1 extends SuperClass{
}
}
Yes, this is how double dispatch works, you have to override the accept method in each subclass like this:
private static abstract class NodeWithChildren implements DomNode {
/* snip */
public void accept(DomNodeVisitor visitor) {
for (DomNode child : children) {
child.accept(visitor);
}
}
}
private static class BodyNode extends NodeWithChildren {
public void accept(DomNodeVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
visitor.visited(this);
}
}
private static class DivNode extends NodeWithChildren {
public void accept(DomNodeVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
visitor.visited(this);
}
}
}
BodyNode is a NodeWithChildren
DivNode is a NodeWithChidren
NodeWithChildren is a DomNode
DomPrinterVisitor is a DomNodeVisitor
DomNodeVisitor's visitor can visit "BodyNode" or "DivNode, But you are passing "NodeWithChildren" to visit.
Here BodyNode is a NodeWithChildren but NodeWithChildren is not BodyNode/
Theary is if B extends A, you can say B is a A/ not A is a B.