When a subclass is instantiated, is only one object created? - java

Since many constructors also call the superclass constructor, it seems like one could think that both the subclass and the superclass are instantiated when a subclass is instantiated; i.e. more than one object is created.
Is still just one object created?
Thank you

Just one object, even if the super's constructor is called you are just performing additional instantiation on the one object.

Yes only one object is created

Just one object is created in memory.

At least one object is created. Who knows how many objects are created in the constructor?
class X extends Y
{
Object [ ] objects ;
X ( int n )
{
super ( ) ;
objects = new Object [ n ] ;
for ( int i = 0 ; i < n ; i ++ )
{
objects [ i ] = new Object ( ) ;
}
}
}

Einstein is attributed a saying: explanations should be as simple as possible, but no simpler. The simple answer 'only one object' may be perhaps true, but misses a lot of important information.
As Nick asked, we can invoke the superclass constructor. So that the superclass constructor is 'somewhere', even though I instantiated only the subclass. Is easy to reason that the instance of the subclass must include all the members of the superclasses (all of them, up to Object). In principle all this pile of variables and methods is the subclass instance. These variables and methods must include also variables not inherited by the subclass. So that the instance is not just what the subclass declares or inherits. I.e. a Cat is-a Mammal, even if Mammal declares some member that Cat doesn't inherit (a poor Java design decision, IMO).
For example, if the superclass has a private variable 'priv', and public accessors getPriv() setPriv(), subclass can invoke the accessors, therefore accessing the variable, modifying state, etc. Yet 'priv' itself is not anywhere to be found in the subclass .class file. So that there is more to the instance than 'just the class'.
I leave to some other discussion the rationale behind 'subclass doesn't inherit private members, etc.'. Never made any sense to me (the instance variables are this instance's; so what access control are you talking about? an object can't access its own parts?! ... anyways ... that was the designers decision)
BTW the JVM spec says nothing (and indeed, shouldn't say anything) about how to implement the inheritance semantics. One possible solution (which may or may not be what any of the JVMs do) would be to create full instances of all the ancestor classes when an instance of the subclass is created. Why not?. It is unlikely anyone will come with an authoritative source declaring that this shall not be done. Certainly the JVM spec doesn't say that.
If someone can contribute a pointer to actual JVM implementation information on this topic, that would be illuminating. I couldn't find it by google'ing. Neither could find an authoritative confirmation of the 'just one object' assertion. May be. I don't know. Conceptually, as a Java language construct? sure! but with 'clarifications'. Implementation-wise, i.e. 'in memory'? may be, may be not.
-Polo

Related

Is there a point in upcasting "this" reference in Java?

I have come across a weird piece of code. I was wondering if there is any usage for it.
class C extends B {
int xB = 4;
C() {
System.out.println(this.xB);
System.out.println(super.xB);
System.out.println(((B)this).xB); // This is the weird code.
}
}
Program prints 4, 10, 10. public xB field of class B has the value 10.
In Java, you can only directly inherit from a single class. But you can have multiple indirect superclasses. Could this be used in upcasting the "this" reference to one of those? Or is this bad programming practice and i should forget about it?
So "((B)this)" basically acts as if it is "super". We could just use super instead of it.
It does NOT generally do the same thing as super.
It does in this case, because fields do not have dynamic dispatch. They are resolved by their compile-time type. And you changed that with the cast.
But super.method() and ((SuperClass)this).method() are not the same. Methods are dispatched at runtime based on the actual type of the instance. The type-cast does not affect this at all.
I was wondering if people are using this structure to upcast "this" to indirect superclasses.
They don't have to, because they don't duplicate field names like that.
It is bad practice to shadow an inherited (visible) field in a subclass (exactly because it leads to confusion like this). So don't do that, and you want have to have this cast.
And you cannot "upcast to indirect superclasses" at all where methods are concerned: You can call super.method() directly (if you are in the subclass), but not something like super.super.method().
this is an instance of C, it can be upcasted to its direct (e.g. B) or indirect (e.g Object) parent.
C c = this;
B b = (B)c;
Object o = (Object)c;
Is this bad programming practice and I should forget about it?
It's a workaround since polymorphism doesn't work for fields. It's a bad practice. Why would C need to declare xB if it's already defined in B and B can grant access to its subclasses to access and work with the field? It's weird, indeed.

In java , can we pass superclass Object to subclass reference?

In java, can we pass superclass Object to subclass reference ?
I know that it is a weird question/practically not viable,
but I want to understand the logic behind this
Why is it not allowed in java.
class Employee {
public void met1(){
System.out.println("met1");
}
}
class SalesPerson extends Employee
{
#Override
public void met1(){
System.out.println("new met1");
}
public void met2(){
System.out.println("met2");
}
}
public class ReferenceTest {
public static void main(String[] args) {
SalesPerson sales = new Employee(); // line 1
sales.met1(); // line 2
sales.met2(); // line 3
}
}
What would have happened if Java allowed compilation of line 1?
Where would the problem arise?
Any inputs/link are welcomes.
If your SalesPerson sales = new Employee(); statement was allowed to compile, this would have broken the principles of Polymorphism, which is one of the features that the language has.
Also, you should get familiar with that does compile time type and runtime type mean:
The compile-time type of a variable is the type it is declared as, while the runtime type is the type of the actual object the variable points to. For example:
Employee sales = new SalesPerson();
The compile-time type of sales is Employee, and the runtime type will be SalesPerson.
The compile-time type defines which methods can be called, while the runtime type defines what happens during the actual call.
Let's suppose for a moment that this statement was valid:
SalesPerson sales = new Employee();
As I said, the compile-time type defines which methods can be called, so met2() would have been eligible for calling. Meanwhile, the Employee class doesn't have a met2() and so the actual call would have been impossible.
No. It makes zero sense to allow that.
The reason is because subclasses generally define additional behavior. If you could assign a superclass object to a subclass reference, you would run into problems at runtime when you try to access class members that don't actually exist.
For example, if this were allowed:
String s = new Object();
You would run into some pretty bad problems. What happens if you try to call a String method? Would the runtime crash? Or perhaps a no-op would be performed? Should this even compile?
If the runtime were to crash, you could use runtime checks to make sure the objects you receive will actually contain the methods you want. But then you're basically implementing guarantees that the Java type system already provides at compile-time. So really that "feature" cost you nothing but a bunch of type-checking code that you shouldn't have had to write in the first place.
If no-ops were executed instead of nonexistent methods, it would be extremely difficult to ensure that your programs would run as written when the members you want to access don't exist, as any reference could really be an Object at any point. This might be easy to handle when you are working on your own and control all your code, but when you have to deal with other code those guarantees essentially vanish.
If you want the compiler to do the checking, assuming compiler writers don't hunt you down and give you a stern talking-to -- well, you're back to "normal" behavior once more. So again, it's just a lot of work for zero benefit.
Long story short: No, it's not allowed, because it makes zero sense to do so, and if a language designer tried to allow that they would be locked up before they could do any more harm.
If you inherit from a class, you always specialize the common behavior of the super class.
In your example, the SalesPerson is a special Employee. It inherits all behavior from the super class and can override behavior to make it different or add new behavior.
If you, as it is allowed, initialize a variable of the super type with an instance of the sub type like Employee e = new SalesPerson(), then you can use all common behavior on that variable.
If instead, you were possible to do the other way round, there might be several uninitialized members in the class.
You find this very often when using the Java Collection API, where for example you can use the common List class on operations like iterating through it, but when initializing it, you use for example the sub class ArrayList.

Why does having static members make a language less object-orientated?

I'm learning Scala at the moment and I came across this statement in Odersky's Programming Scala 2nd edition:
one way in which Scala is more object-orientated than Java is that classes in Scala cannot have static members.
I'm not sufficiently experienced in either Java or Scala to understand that comparison. Why does having static members make a language less OO?
Odersky's statement is valid and significant, but some people don't understand what he meant.
Let's say that in Java you have a class Foo with method f:
class Foo {
int f() { /* does something great */ }
}
You can write a method that takes a Foo and invokes f on it:
void g(Foo foo) { foo.f(); }
Perhaps there is a class SubFoo that extends Foo; g works on that too. There can be a whole set of classes, related by inheritance or by an interface, which share the fact that they can be used with g.
Now let's make that f method static:
class Foo {
static int f() { /* does something great */ }
}
Can we use this new Foo with g, perhaps like so?
g(Foo); // No, this is nonsense.
Darn. OK, let's change the signature of g so that we can pass Foo to it and have it invoke f.
Ooops -- we can't. We can't pass around a reference to Foo because Foo is not an instance of some class. Some people commenting here are confused by the fact that there is a Class object corresponding to Foo, but as Sotirios tried to explain, that Class object does not have an f method and Foo is not an instance of that class. Foo is not an instance of anything; it is not an object at all. The Class object for Foo is an instance of class Class that has information about Foo (think of it as Foo's internal Wikipedia page), and is completely irrelevant to the discussion. The Wikipedia page for "tiger" is not a tiger.
In Java, "primitives" like 3 and 'x' are not objects. They are objects in Scala. For performance your program will use JVM primitives for 3 and 'x' wherever possible during execution, but at the level you code in they really are objects. The fact that they are not objects in Java has rather unfortunate consequences for anyone trying to write code that handles all data types -- you have to have special logic and additional methods to cover primitives. If you've ever seen or written that kind of code, you know that it's awful. Odersky's statement is not "purism"; far from it.
In Scala there is no piece of runtime data that is not an object, and there is no thing you can invoke methods on that is not an object. In Java neither of these statements in true; Java is a partially object-oriented language. In Java there are things which are not objects and there are methods which aren't on objects.
Newcomers to Scala often think of object Foo as some weird replacement for Java statics, but that's something you need to get past quickly. Instead think of Java's static methods as a non-OO wart and Scala's object Foo { ... } as something along these lines:
class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass // the only instance of it
Here Foo is a value, not a type, and it really is an object. It can be passed to a method. It can extend some other class. For example:
abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }
Now, finally, you can say
g(Foo)
It is true that a "companion object" for a class is a good place to put non-instance methods and data for the class. But that companion object is an object, so the usual rules and capabilities apply.
The fact that in Java you put such methods on non-objects -- limiting how they can be used -- is a liability, not a feature. It is certainly not OO.
I am not sure I completely buy that argument, but here is one possible reasoning.
To an object-oriented purist, everything should be an object, and all state should be encapsulated by objects. Any static member of a class is by definition state which exists outside of an object, because you can use it and manipulate it without instantiating an object. Thus, the lack of static class members makes for a more pure object-oriented language.
Well, with static members like methods you don't have any objects to create and nevertheless you can call such static methods. You only need the static classname in order to set the namespace for these methods, for example:
long timeNow = System.currentTimeMillis(); // no object creation
This rather gives a feeling like in procedural languages.
static members belongs to the Class not to the object while the main concept of oop lies among the relation between the individual objects of dirrefer Class.
A static method in Java is one that operates on the class itself, and doesn't need an Object to be created first. For example, this line:
int c = Integer.parseInt("5");
Integer.parseInt() is static because I didn't have to go Integer i = new Integer(); before using it; this isn't operating on any particular object that I've created, since it's always going to be the same, and is more like a typical procedural function call instead of an object-oriented method. It's more object-oriented if I have to create an object for every call and we encapsulate everything that way instead of allowing static to use methods as faux-procedural-functions.
There are several competing definitions of what exactly object-orientation means. However, there is one thing they all can agree on: dynamic dispatch is a fundamental part of the definition of OO.
Static methods are static (duh), not dynamic, ergo they are by definition not object-oriented.
And logically, a language that has a feature which isn't object-oriented is in some sense "less OO" than a language which doesn't have said feature.

Using superclass type for subclass instance

I know this question has been asked a lot, but the usual answers are far from satisfying in my view.
given the following class hierarchy:
class SuperClass{}
class SubClass extends SuperClass{}
why does people use this pattern to instantiate SubClass:
SuperClass instance = new SubClass();
instead of this one:
SubClass instance = new SubClass();
Now, the usual answer I see is that this is in order to send instance as an argument to a method that requires an instance of SuperClass like here:
void aFunction(SuperClass param){}
//somewhere else in the code...
...
aFunction(instance);
...
But I can send an instance of SubClass to aFunction regardless of the type of variable that held it! meaning the following code will compile and run with no errors (assuming the previously provided definition of aFunction):
SubClass instance = new SubClass();
aFunction(instance);
In fact, AFAIK variable types are meaningless at runtime. They are used only by the compiler!
Another possible reason to define a variable as SuperClass would be if it had several different subclasses and the variable is supposed to switch it's reference to several of them at runtime, but I for example only saw this happen in class (not super, not sub. just class). Definitly not sufficient to require a general pattern...
The main argument for this type of coding is because of the Liskov Substituion Principle, which states that if X is a subtype of type T, then any instance of T should be able to be swapped out with X.
The advantage of this is simple. Let's say we've got a program that has a properties file, that looks like this:
mode="Run"
And your program looks like this:
public void Program
{
public Mode mode;
public static void main(String[] args)
{
mode = Config.getMode();
mode.run();
}
}
So briefly, this program is going to use the config file to define the mode this program is going to boot up in. In the Config class, getMode() might look like this:
public Mode getMode()
{
String type = getProperty("mode"); // Now equals "Run" in our example.
switch(type)
{
case "Run": return new RunMode();
case "Halt": return new HaltMode();
}
}
Why this wouldn't work otherwise
Now, because you have a reference of type Mode, you can completely change the functionality of your program with simply changing the value of the mode property. If you had public RunMode mode, you would not be able to use this type of functionality.
Why this is a good thing
This pattern has caught on so well because it opens programs up for extensibility. It means that this type of desirable functionality is possible with the smallest amount of changes, should the author desire to implement this kind of functionality. And I mean, come on. You change one word in a config file and completely alter the program flow, without editing a single line of code. That is desirable.
In many cases it doesn't really matter but is considered good style.
You limit the information provided to users of the reference to what is nessary, i.e. that it is an instance of type SuperClass. It doesn't (and shouldn't) matter whether the variable references an object of type SuperClass or SubClass.
Update:
This also is true for local variables that are never used as a parameter etc.
As I said, it often doesn't matter but is considered good style because you might later change the variable to hold a parameter or another sub type of the super type. In that case, if you used the sub type first, your further code (in that single scope, e.g. method) might accidentially rely on the API of one specific sub type and changing the variable to hold another type might break your code.
I'll expand on Chris' example:
Consider you have the following:
RunMode mode = new RunMode();
...
You might now rely on the fact that mode is a RunMode.
However, later you might want to change that line to:
RunMode mode = Config.getMode(); //breaks
Oops, that doesn't compile. Ok, let's change that.
Mode mode = Config.getMode();
That line would compile now, but your further code might break, because you accidentially relied to mode being an instance of RunMode. Note that it might compile but could break at runtime or screw your logic.
SuperClass instance = new SubClass1()
after some lines, you may do instance = new SubClass2();
But if you write, SubClass1 instance = new SubClass1();
after some lines, you can't do instance = new SubClass2()
It is called polymorphis and it is superclass reference to a subclass object.
In fact, AFAIK variable types are meaningless at runtime. They are used
only by the compiler!
Not sure where you read this from. At compile time compiler only know the class of the reference type(so super class in case of polymorphism as you have stated). At runtime java knows the actual type of Object(.getClass()). At compile time java compiler only checks if the invoked method definition is in the class of reference type. Which method to invoke(function overloading) is determined at runtime based on the actual type of the object.
Why polymorphism?
Well google to find more but here is an example. You have a common method draw(Shape s). Now shape can be a Rectangle, a Circle any CustomShape. If you dont use Shape reference in draw() method you will have to create different methods for each type of(subclasses) of shape.
This is from a design point of view, you will have one super class and there can be multiple subclasses where in you want to extend the functionality.
An implementer who will have to write a subclass need only to focus on which methods to override

the static concept in java

I can't seem to understand the static key word (java) so I googled it up and viewed a thread in this website, though I'm sure the answer was conclusive and clear -it always is over here- I didn't seem to understand it for two reasons; I'm not a native English speaker and the language was a bit vague for me, and it lacked exemples of use in classes, instance of classes, interfaces (if possible), instance of interfaces and variables, lists and arrays ect.
I would really appreciate any help and please keep the English as simple as possible ;)
Thank you
Aditsan
Note from editor: Please note that the original poster is asking for examples, and is not a native English speaker as you provide answers. From the comments, it appears that OP doesn't understand the concept well enough to ask about the parts that don't make sense yet, so examples would be awesome! It may take extra details and multiple different explanations to find the combination of answers that works best.
I think it helps to understand what non-static means, i.e. field/methods/... that are declared without the keyword static.
Every field declared without the keyword static exists as part of an object. If you have two objects, each of these two objects has a field with possibly different contents:
class X {
int f;
}
X x1 = new X();
X x2 = new X();
x1.f = 5;
x2.f = 10;
// x1.f still is 5
However, static fields exist not per object, but per class. So in the following example, there is only one field g no matter how many (if any!) objects of class Y you have:
class Y {
static int g;
}
Y y1 = new Y();
Y y2 = new Y();
y1.g = 5;
y2.g = 10;
// y1.g is 10, because y1.g and y2.g mean the exact same thing
I personally think accesses to static fields should be made using the class (Y.g) instead of mentioning object instances (y1.g), so that the existence without any object instance is more explicit.
For methods the difference is that non-static methods are associated to an object instance, which can be accesses using this inside the method. When invoking a method declared with void m() you can access non-static (and static) fields of the object it is invoked on (so for x1.m() from the example above you can get to the field containing 5, for x2.m() you can access the field containing 10.
Static methods, however, can be invoked without having a (corresponding?) object around. If the declaration is static void n() inside class Y, you can call this method using Y.n() or y1.n() (if y1 is an instanceof Y, as above). Here, too, I prefer the first way of writing it down. Because in static methods you do not have a reference to the object instance (which is named this in non-static methods), you cannot access specific non-static fields from inside a static method - simply because there is no clear association to a specific object.
Regarding static and class definitions: This is rather advanced. You can declare a class inside another class. If the inner class is not static, every object instance of the inner class also has a reference to an instance of the outer class (which also means that you only can create an instance of the inner class if you have an instance of the outer class). This is not always what you want. By declaring the inner class static it just exists and can be used, more or less, like a class defined in its own file.
Basically, static implies/provides two things:
1) Only one instance of an "item" exists in the whole system (JVM)
2) Static "items" are also context/state free
To explain (1) above: Suppose you have a Meal Token issuer. No matter how many users/processes are there in the system, all tokens must be issued by a single "thing". You would develop that "thing" as static. You would then decide what that "thing" is. It could be a class that does a complex operation and implements a complex business rule. Then you would have a single static class issuing tokens in "a single uniform way" for the whole system. Some times, all that matters is that the token should be "static" but how it is issued could be non-static. Then you would simply implement a "Static" token counter.
To explain (2) : Going by what is said for (1) above, you can easily see why it is important that the static "things" operate in a context-free manner. That is, they do not know who calls them or for what purpose. When they are called, they do not borrow anything from the past, they need all inputs from the current caller, and they just do their job, and remember nothing for the future.

Categories