Can I override a new instance of a class object? - java

I'm not sure what it's called but you can override methods easily with:
Apple foo = new Apple(){
public void devour(){
//Devour apple
}
};
And you can get the Class of an object with getClass.
Is it possible to do something like this:
Apple a = new Apple();
Class<? extends Apple> B = a.getClass();
Apple c = new B(){
public void polish(){
//Polish apple
}
};
Side Note: I'm asking this question because I specifically want to override a single method in the current swing UI class for a component returned by UIManager.getUI(component).getClass() in this code.

In the first code snippet you are creating an anonymous subclass of Apple which overrides the devour() method, and then instantiating foo as an instance of this anonymous subclass.
In the second example, and in your goal, you cannot change the class/type of an object reference after that object already exists.

Related

Convert a Java Method object to a Function object [duplicate]

class A {
public static void foo() {}
}
class B {
public static void foo() {}
}
I have Class clazz = A.class; or B.class;
How do I access this via "clazz" assuming it might be assigned either 'A' or 'B'
It is only possible to access those methods using reflection. You cannot reference a class directly, only an instance of type Class.
To use reflection to invoke methodname(int a, String b):
Method m = clazz.getMethod("methodname", Integer.class, String.class);
m.invoke(null, 1, "Hello World!");
See Class.getMethod() and Method.invoke()
You may want to think about your design again, to avoid the need to dynamically call static methods.
You can invoke a static method via reflection like this :
Method method = clazz.getMethod("methodname", argstype);
Object o = method.invoke(null, args);
Where argstype is an array of arguments type and args is an array of parameters for the call. More informations on the following links :
getMethod()
invoke()
In your case, something like this should work :
Method method = clazz.getMethod("foo", null);
method.invoke(null, null); // foo returns nothing
You cannot access static methods without an explicit reference to the class.
No inheritance here, sorry, so you must either do:
A.foo()
or
B.foo()
If you really need it, you will have to do a check:
Object o = .... // eith an A or B instance.
if( o instanceof A ) {
A.foo()
} else {
B.foo()
}
But why don't you just make those functions instance functions, and let them implement an interface?
Okey, you have a class object. Then do:
Class c = ...;
c.getMethod("foo").invoke(null); // null to invoke static methods
According to my lack of knowledge the need for the requested construct is given by the fact that an interface doesn't offer the possibility of static abstract methods. Here is an example:
public enum Cheese implements Yumy {
GOUDA(49),
ESROM(40),
HWARTI(38);
private int percentage;
private Cheese(int fat100) {...} constructor
public void yamyam() {...} // as in Yumy
public static Cheese getByFat(int fat100) {...} // no chance to be part
of interface
};
I hope this isn't making too many assumptions or deviating too far from your question, but if your two classes share a common supertype and creating an instance is tolerable then you can:
Implement a common interface
Create an instance of the object via myClass.newInstance() (class must have an empty constructor)
Call the static method from the instance object.
interface Foo {
void foo();
}
class A implements Foo {...}
class B implements Foo {...}
<T extends Foo> public void something(Class<T> clazz) {
T myInstance = clazz.newInstance();
myInstance.foo();
}
...
something(A.class);
It's a little bizarre but in my case it proved to be useful, and I began by asking the very same question that you did.

Strange behavior, about Interface to be a member of a class in Java

interface SomeInterface {
String test = "hello";
}
public class SomeCls {
SomeInterface sif;
public static void main(){
SomeCls cls = new SomeCls();
cls.sif = null;
System.out.println(cls.sif.test); // still work.
}
}
I'm coming from c++, question is:
1) because interface is a "abstract" type, how can it be used as a member, I mean, how to init it?
2) I know, the member "sif" may be just a reference(not like the c++ reference, more like a pointer in c), but since I set it reference to null. how can it still output the interface's field?
Variable declared inside an interface would be static by default. So it doesnt make sense to call that variable using reference .
You can call like SomeInterface.test
About your first question.
You can't create instance of interface. But you can create implementation of interface:
public class SomeClass implements SomeInterface{
...
}
And as you correctly noted, variable of interface type "may be just a reference"
SomeInterface sif = new SomeClass();
You can consider interface like a contract, description of behavior, that class (witch implements this interface) promise to provide.
Another point, there is no multiple inheritance in Java, but class can implement multiple interfaces.

How to get the type of object reference of instance?

Given an interface, an abstract class and a concrete class
interface Interface {
}
abstract class AbstractClass {
}
class C extends AbstractClass implements Interface {
}
I instantiate two instances of my concrete class C like so
Interface a = new C();
AbstractClass b = new C();
System.out.println(getObjectReferenceName(a));// return some.package.Interface
System.out.println(getObjectReferenceName(b));// return some.package.AbstractClass
/*
it return the class name of Object refernce
*/
String getObjectReferenceName(Object o){
// todo
return "class name";
}
How can I get the class name of the reference type?
That is -
a's object reference is some.package.Interface.
b's object reference is some.package.AbstractClass.
To get the name try
System.out.println(a.getClass().getInterfaces()[0]);
System.out.println(b.getClass().getSuperclass());
Output:
interface testPackage.InterfaceClass
class testPackage.AbstractClass
If you want to check if an object is an instance of a class, try instanceof.
Edit:
If you want to get the type the variables were declared with, you can use reflection. This works if these are fields, in other words, if they are declared as class fields, no local variables.
System.out.println(Test.class.getDeclaredField("a").getType()); // Test is the name of the main' method class
System.out.println(Test.class.getDeclaredField("b").getType());
a.getClass().getInterfaces() gives you Array that contain object of Class class that represent all interfaces implemented by class of object a.
i.e. a.getClass().getInterfaces()[0].getName() gives you InterfaceClass
b.getClass().getSuperclass().getName() gives you AbstractClass
This might seem like a stupid answer but
// right here
// |
// v
Interface a = new C();
Also you've added a hypothetical method that returns the name of the reference type but
static String getReferenceType(Object o) {
// the reality is o is always Object
return Object.class.getName();
}
There's not really a situation where you need to do some program logic based on the type of a reference because you always know the type of the reference. It's in your own declaration. The situation where you need to call a method or instanceof operator is when you have it the other way: when you don't know the actual type of the object.
You can go the java.lang.Class to access methods and then invoke them to get different information. If you want to know which class is based to instantiate an object, you could use referenceVariableName.getClass(); to get its super class, referenceVariableName.getClass().getSuperclass() to do that; to know interfaces, then you can use referenceVariableName.getClass().getInterfaces()[0] (the first interface since there are many interfaces maybe).
Try this:
public class ObjectReferenceName {
Interface a = new C();
AbstractClass b = new C();
C c =new C();
static String getObjectReferenceName(String fieldName) throws NoSuchFieldException{
return ObjectReferenceName.class.getDeclaredField(fieldName).getType().getName();
}
public static void main(String[] args) throws NoSuchFieldException {
System.out.println(ObjectReferenceName.getObjectReferenceName("a"));
System.out.println(ObjectReferenceName.getObjectReferenceName("b"));
System.out.println(ObjectReferenceName.getObjectReferenceName("c"));
}
}

Code seems to be instantiating an unimplemented interface

I've read a few questions about instantiating an interface, but either none of them addressed my question, or else I didn't fully understand what was happening.
Observer observer = (Observer) observers.elementAt(i);
I've never encountered a statement like this. Looks like a weird way of instantiating an object. However, Observer is an interface, and the class that this statement is made in (class is abstract, if that has any bearing) doesn't implement the interface.
Could anyone explain to me what exactly is happening?
The statement is retrieving an object from some sort of collection. The object is explicitly cast to the type Observer and assigned to observer variable. The object is not being instantiated, just retrieved. The explicit cast makes this statement slightly dangerous because there is no way to guarantee the object retrieved from the collection implements Observer.
First of all, it doesn't instantiate anything, it just grabs an instance of some implementation of Observer from a collection (I assume it's Vector by the method name).
So this is what's going on
Vector observers = new Vector();
observers.add(new ObserverImpl());
Observer o = (Observer) observers.elementAt(0);
Note that this a very oldschool way of doing things, you shouldn't use Vector anymore and you should always use generics, so this code should be rewritten as
List<Observer> observers = new ArrayList<>();
observers.add(new ObserverImpl());
Observer o = observers.get(0); //you don't need to cast anymore because of generics
An interface is a type of contract that ensures that the methods defined on that interface is implemented. If an object implements an interface it has to have to cater for all the methods defined on it.
In your code example an object is cast to a variable of type Observer which means you can call any of the Observer methods. It does not change the object, nor is it instantiated.
First of all, an abstract class is a class who can't be instantiated, sometimes there is only one method abstract, sometimes the whole class is abstract. You'll have to extend such a class. It allows you to implement functionality in a base class.
An interface is a contract for a class and is implemented by the keyword implements. It Provides you the method calls, there is no functionallity in interfaces.
Now to your question:
Observer observer = (Observer) observers.elementAt(i);
This ensures an object ( containing methods like: equals, hashCode or toString) has the methods of an interface.
ex in pseudocode:
interface Printable{
String print();
}
and its "implementation":
public class MyDocument implements Printable{
#Override
public String print(){
// do the print thing
}
public void additionalMethod(){
// do some other stuff
}
}
and its use
Printable doc = new MyDocument(); // now we ensure that we can call .print()
An interface is a contract to its implementing classes. It is perfectly legal to write a code that you encountered .
Lets understand this with a simple example :
create an interface Animal
public interface Animal {
public void eat();
}
create two implementing classes as Horse and Cat that implements this interface.
public class Cat implements Animal {
public void eat() {
System.out.println("Cat eats Mouse.");
}
}
public class Horse implements Animal {
public void eat() {
System.out.println("Horse eats hay.");
}
}
Now test the behavior using a Tesy class :
public class Test {
public static void main(String[] args) {
Horse h = new Horse();
Cat c = new Cat();
Animal a = (Animal)h;
a.eat();
a = (Animal)c;
a.eat();
}
}
The output would be :
Horse eats hay.
Cat eats Mouse.
This kind of behavior supports dynamic polymorphism or run time polymorphism.
Even though you have the reference of Animal object you hold the objects of Horse or Cat which implements the methods so you can call them. An Animal reference holding the object of class that implements it can call only those methods which are declared in the interface Animal.

Why doesn't Java allow hiding static methods by instance methods?

As shown in http://docs.oracle.com/javase/tutorial/java/IandI/override.html, Java does allow
Overriding an instance method by an instance method and
Hiding a static method by a static method
My question is why Java doesn't allow hiding a static superclass method by an instance method. This could be done like this:
class Base {
static void foo () {}
}
class Derived extends Base {
void foo () {}
void access () {
foo ();
Base.foo ();
}
}
I don't see any particular issue with the above approach - it is only as "messy/complex" as the (allowed) hiding of statics already is.
I suspect it is to avoid confusion with dealing with the base class. In fact I imagine the designers didn't see an obvious way this should behave.
class Base {
static void foo () {}
}
class Derived extends Base {
void foo () {} // say this compiled
}
Base b = new Derived()
b.foo(); // should the static or the virtual method be called?
Should b.foo() call Base.foo() or should it potentially call Derived.foo()?
Simple answer: that would be the mess.
Concrete answer: what to call in that case Derived.foo()? Base.foo() can't be called as it's hidden (as per you), Derived.foo() can't be called as it's not static.
Because, one are like Bananas and the other ones are Apples.
Explaination:
Static Methods are created when reading the Class-Structure
Methods are created when a object of a class is created.
Example:
Foo.bar();
is something different than
new Foo().bar();
Guess which one is called?
Foo f = new Foo();
f.bar();
Another to add here is:
1. Static methods belong at the class level. So u cannot override method in the derived class.
as simple its called hiding. :)
2. Instance methods belong to the objects, so objects are overrided. So we can override in the derived class.
Above other comments give a good example have a look into it..
Regards
Punith

Categories

Resources