If I have an abstract class in java named Foo and it has an implementor named Bar then I want to know the following.
lets say Foo looks something like
public abstract class Foo {
Service serviceFoo
...
}
And Bar is
public class Bar extends Foo {
...
}
Also, lets assume I have an instance with Foo, named foo, currently that has serviceFoo instantiated
If I then declare:
Foo foo = new Bar();
will this create a a new instance of Bar that has serviceFoo instantiated or not? E.g. will that field be inherited and instantiated or just inherited?
When you call new Bar();, the constructor for Foo is called implicitly. If Foo's constructor instantiates serviceFoo then so will Bar. If Foo relies on someone else to instantiate serviceFoo then Bar will do the same.
Existing instances of either Foo or Bar have no bearing on what goes on when a new instance is made. Only what code gets executed in the constructor (or what gets passed in as a parameter) has an impact on the new object.
No, inheritance does not happen between instances; only between class definitions.
When you instantiate new Bar(), serviceFoo will be instantiated according to its declaration in Foo. In the current case, it has no instantiation in Foo, so it would be a null reference in the new instance of Bar.
Also, you should know that all non-primitives in Java are reference types. That is, foo is not a Foo, but a reference to a Foo. When you assign your new Bar() to foo, you are reassigning its reference to a new object entirely.
Edit: One more, minor nitpick - if you already have an instance of Foo named foo as you claim, then the line
Foo foo = new Bar();
would not compile as it is a redeclaration of foo.
No, serviceFoo won't be instantiated. The line
Foo foo = new Bar();
drops the reference to the "old" object referenced by foo and creates a brand new one. In particlar, it does not "convert" the old foo (of type Foo) into an object of type Bar.
When you say Foo foo = new Bar(), you are creating a brand new object. This means that Bar is created from scratch and any instance variables are also initialized. If it inherits from a super class, like Foo, then those inherited variables are also initialized.
There is no way the parameterless constructor Bar() can know about an outside Service serviceFoo and somehow set it to that value.
If you want to do that, you need to pass in the reference to serviceFoo in the constructor.
Foo foo1 = new Bar();
foo1.serviceFoo = new Service();
// do something with that serviceFoo
Foo foo2 = new Bar(foo1.serviceFoo); // make sure you define this constructor
Since serviceFoo is an instance variable (i.e. it's not declared static) any existing instances of Foo that have set this field will not have any effect on any new instances you create.
Assuming Bar doesn't set it, all you'll get is the field inherited and not instantiated with the new instance.
If you change your base class' code to
public abstract class Foo {
Service serviceFoo = new Service(...);
......
}
Then bar will have an instance of Service when bar is instantiated.
Inheritance is used for:
to enable code reuse
to promote polymorphism
Inheritance means when a child class extends or inherit class know as inheritance.
public class Parent {
public void dostuff() {
System.out.println("i am in parent");
}
}
public class Child extends Parent {
public void dostuff() {
System.out.println("i am in child");
}
}
public class Test {
public static void main(String[] args) {
Parent p = new Parent();
Parent p1 = new Child();
p.dostuff();
p1.dostuff();
}
}
Related
Here is my question. I have a super class with an abstract method in it.
public abstract class Base{
public abstract Boolean foo();
}
public class sub extends Base{
#Override
public Boolean foo(){
System.out.printLn("This is foo in the sub class!");
}
}
so When I go to the main and try this code
Base b = new sub();
b.foo();
I got no error and message shows on my screen. My assumption is the compiler looks at the b object and sees it as a Base object then it goes to the foo from the Base object and sees there is no implementation afterwards it checks out the foo from the child and then it sees the method foo is implemented there so it shows the message. Am I right?
Compiler does not see if the method is implemented by subclass or not. It only checks whether method called by the a particular class type reference is present in the class itself or not. At runtime it decides which method to call means Base class version or Subclass version.
So you are only right upto "My assumption is the compiler looks at the b object and sees it as a Base object then it goes to the foo from the Base" statement.
Compiler does not do so much of processing. Here in your case
You have created the reference variable as of your superclass which will hold the object of child class.
Now when you are calling the method it is directly calling the method present in your subclass based on your object type.
I am adding you code with my comments for your reference.
1) Abstract class having only method declaration
public abstract class Base {
public abstract Boolean foo(); //method declaration
}
2) Child class extending your parent class where you have to implement the method,If you are declaring this class as concrete class.
public class sub extends Base {
#Override
public Boolean foo() {
System.out.printLn("This is foo in the sub class!");
}
}
3) Here you have declared reference variable of your parent type that is storing the object of you child class
Base b = new sub();
4) when this line will get executed compiler will check, what is the type of object and call that method on the basis of object type.It will not invoke methods on the type of reference variable.
b.foo();
I ll try to set it as simple as possible because it confuses me too.
I got a method returning an object of type Class i.e.
public Class foo(){...}
When I call this method I'm keeping the result in a variable of type Class i.e.
Class obj = new foo();
foo() can return many different classes BUT all of them contain the same method bar().
How can I invoke that method from my obj variable?
I tried obj.bar() but the IDE doesn't seem to like it. I get
Error:(59, 34) error: cannot find symbol method bar()
It seems like you want to group behaviors, that's what Java interfaces do:
interface Barer {
String bar();
}
class Foo implements Barer {
String bar() {
return "I'm a Foo";
}
}
class Fooz implements Barer {
String bar() {
return "I'm a Fooz";
}
}
Then in you code you can have something like:
Barer obj;
if (something) {
obj = new Foo();
} else {
obj = new Fooz();
}
obj.bar()
It makes little sense in fact to store the return value of a constructor in a Class object.
If you really are in the case that you need a Class object (remember that it will just point to the Class, not to the instance you have created), you can use Java reflection:
Class obj = new foo();
Method method = obj.getDeclaredMethod("bar");
method.invoke(null);
if method foo() returns Class, it means it don't return actual instance of the objet on which you want to call bar() method, but the class itself, so it's not possible to call method bar() on Class as Class.class don't have a method bar.
In your code example there is some mistake
Class obj = new foo();
The keyword new mean you're creating a new instance of a class, not you're calling a method on an object.
In fact the right approach would be to use interfaces.
Instead of returning Class from foo method, declare an interface,
public interface MyInterface {
public void bar();
}
and make foo() returning MyInterface instead of Class.
Then you can do
MyInterface obj = tmp.foo();
obj.bar()
If all returned values are objects of classes that implements the same method, you should declare that method in separate interface and let them implement it. Later on you can use generic wildcard like <? extends BarInterface> or change return type to BarInterface.
public interface BarInterface{
public void bar();
}
and
public <T extends BarInterface> foo(){...}
or
public BarInterface foo() {...}
I came across this pattern in some source codes:
public abstract class Foo {
void doSomething(){
System.out.println("...");
}
private class FooBar extends Foo{
void doAnything(){
Foo.this.doSomething();
}
}
}
Whats the significance of
Foo.this.doSomething();
or is it just some cargo cult practice?
Foo.this and this refer to two different objects.
Since FooBar is an inner class defined inside Foo, every instance of FooBar has an instance of Foo associated with it.
this refers to the FooBar instance itself;
Foo.this refers to the outer Foo instance.
See How can "this" of the outer class be accessed from an inner class?
That said, the Foo.this. in the example you show is redundant and can be omitted (unless both Foo and FooBar have a method called doSomething()).
In the example you give this is equivalent to calling doSomething(); directly.
However, if you declared the same method void doSomething() in the FooBar class you would use this notation to signify you call the method of the outer class not the inner.
In the latter case this.doSomething() would not suffice, this still will point to the this member variable of FooBar, that is why you specify specifically the class from which you want to call the method.
Foo.this references outer class Foo's object instance, which is always bound in inner class's object.
You can think to Foo and FooBar as being instanced always together, when Foo is instantiated.
In your case is not necessary, but if you need to pass the Foo object instance to any method that requires it from the inner Foo.Bar, you can do it with:
// some method of some other class (OtherClass.java)
void someFunction( Foo foo )...
// ...
private class FooBar extends Foo{
void doAnything(){
otherClass.someFunction( Foo.this );
}
}
Foo.this refers to outer class object,where as this refers current class object.
According to java docs.It is also called Shadowing
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.
Is there a way for a Java class to have an awareness of its instantiator? For example:
public class Foo() {
public Foo() {
// can I get Bar.myInteger from here somehow
// without passing it in to the constructor?
}
}
public class Bar {
private int myInteger;
public Bar() {
myInteger = 0;
Foo foo = new Foo();
}
}
Is there any particular reason you don't want to pass anything in the constructor?
Simply put, this violates the encapsulation principle... and probably several others as well.
With inner classes, you can.
public class Bar {
private int myInteger;
public class Foo() {
public Foo() {
// you can access myInteger
}
}
public Bar() {
myInteger = 0;
Foo foo = new Foo();
}
}
No, you can't.
What are you trying to do?
You can get some information with a stack trace:
Throwable t = new Throwable();
t.fillInStackTrace();
StackTraceElement[] stt = t.getStackTrace();
then explore the elements of stt[].
You cannot access it the way you want to. But using an inner class might be appropriate here, depending on what problem you are trying to solve. The inner class can access private variables of the outer one.
If they're in the same package, you can change the access level of myInteger to protected and Foo can access it directly, but you still need a reference to Bar unless myInteger is also static. I don't like to do that though, it makes them harder to test.
Aside from that, your options are using setters after instantiating the Foo or passing it to the constructor.
You can only access a private member of another class if you either explicitly pass it to the constructor if you provide getter/setter functions. So the answer to your question is no.
You could force "Instantiators" to use a Factory. But in any case, the "identity" of the object requesting a new instance should be passed as a parameter.
And careful in defining what kind of identity you want to trace. An instance ID? a Class ID?
If Foo were an inner class to Bar, it could see Bar's members.
you can work with inner classes, like this:
public class Bar {
private int myInteger;
public Bar() {
myInteger = 0;
Foo foo = new Foo();
}
class Foo {
Foo() {
int i = Bar.this.myInteger;
}
}
}
regards.
Keeping it simple...
1.
If Foo always needs to know myInteger from Bar then pass it into the constructor.
2.
If Foo only occasionally needs to know myInteger then call a setter after the constructor.
If Foo needs more than myInteger, i.e. the whole Bar object then Bar can pass itself in using the "this" keyword.
public class Foo
{
public Foo(Bar bar)
{
//Do something with Bar
}
}
// Somewhere in Bar (in a non-static method)
new Foo(this);