Is inheritance compile time or runtime in java - java

I was told that inheritance is runtime, but I want to ask that if inheritance is runtime then how does compiler generate error at compile time when we try to access parent class data member via child class object:
class PrivateData {
private int x = 50;
void show() {
System.out.println(x);
}
}
class ChildPrivateData extends PrivateData {
public static void main(String s[]) {
ChildPrivateData c1 = new ChildPrivateData();
System.out.println(c1.x);
}
}

Inheritance is most definitely defined at compile time in Java. I think you're confusing it with polymorphism, which, in a nutshell, states that Java chooses which overridden method to run only at runtime.

You are confused with compile time and runtime . I don't touch your code. But see an example here
String result = returnInt(); // #1
public int returnInt() {
return 1;
}
If you see , at line #1 do you think that compiler execute returnInt() method to give a compile time error ? No right?
And the answer is
All the rules already given to Compiler from Specification. It just checks against them.

Inheritence in java is achieved with the "extends" keyword, which is reserved for compile-time inheritence.
In your case you have defined the Base class variable as private.A private member is not inherited. A private member can only be accessed in the child class through some Base class method.
class PrivateData{
private int x =50;
void show(){
System.out.println(x);
}
}
class ChildPrivateData extends PrivateData {
public static void main(String s[]){
ChildPrivateData c1 = new ChildPrivateData();
System.out.println(c1.show());
}
}

inheritance is always achieched at compile time.the code acquires reusability with
extends keyword even before entering into jvm for verification and thus converting to
bytecode,although we can only use its features at run-time after the creation of the object.
and about private member although it will be inherited by the child class but wont be accessible.

Related

Can this code be considered for member overriding in Java?

Java, in theory, doesn't support member overriding so I was thinking whether this code snippet can be used for overriding members of the class. However, I am not quite sure in what situations this code might fail. I mean, if this works perfectly then it wouldn't go unnoticed right?
It might be a stupid question, but I really want to know what this code might do in different situations which my mind can't think of.
So it will be really great if someone can explain it to me.
Thanks!
class ClassA{
int i = 10;
void eat() {
System.out.println("In Class A: Eating");
}
void bark() {
System.out.println("In Class A: Barking");
}
}
class ClassB extends ClassA{
//int i = 20;
ClassB(){
super.i = 20; //Changing the value of i in class A.
}
void eat() {
System.out.println("In Class B: Eating");
}
}
public class Main{
public static void main(String[] args) {
ClassB b = new ClassB();
System.out.println(b.i);
b.eat();
b.bark();
ClassA ua = new ClassB();
System.out.println(ua.i);
ua.eat();
ua.bark();
ClassA a = new ClassA();
System.out.println(a.i);
}
}
I am not quite sure in what situations this code might fail.
It (sort of) fails on the human reader/conceptual level.
The java language is what it is. This means that java programmers know what to expect, what to do, and what not to do.
And one of the basic rules for inheritance (in java, but also in general): you are extremely cautious regarding fields of your super class(es). Member fields should be considered an internal implementation detail of a class. You don't expose it to the outer world. You don't expose it to your child classes, unless there is a really good reason to do so. And if you really want to do that in java, then the correct way is: using the protected keyword for that field.
Your idea is basically that the child class "knows" about super class fields, and worse: changes that "internal state" at creation time.
Thus, in the real world, such code might quickly lead to all sorts of nasty surprises. Because people in the real world wouldn't expect that a subclass is doing something like, thus they might be really surprised to find "i should be 10, why is it 20" when debugging a problem in a large application.
Long story short: the fact that you can do something doesn't mean that you should do it. To the contrary: good programming is about doing things in "standard" ways that do not surprise your readers.
If you override a method then try to call it from the parent, the parent calls the derived method, even though it wasn't aware of it at definition time.
class A {
public void foo() {
System.out.println("A.foo");
}
public void callFoo() {
this.foo();
}
}
class B {
public void foo() {
System.out.println("B.foo");
}
}
B instance = new B();
instance.callFoo(); // Prints "B.foo"
Now if we try to do the same thing with instance fields, we get the original one.
class A {
public String foo = "A.foo";
public void printFoo() {
System.out.println(this.foo);
}
}
class B {
public String foo = "B.foo";
}
B instance = new B();
instance.printFoo(); // Prints "A.foo"
So we haven't actually overridden anything; we've simply made a new variable that happens to confusingly share the name of an existing one. If it was true overriding, then we would be able to augment the behavior of A methods which use that variable but aren't aware of the subclass.
Simple answer for your question is 'Yes', your eat method of class ClassA is overriding in class ClassB. The easy option to verify, is using #Override annotation.
In a subclass, you can override and overload an instance method. Override means, you are subclass replacing the inherited behavior. Overloading means, you are extending the inherited method.
If you modify your ClassB as follows , it will compile successfully.
class ClassB extends ClassA{
//int i = 20;
ClassB(){
super.i = 20; //Changing the value of i in class A.
}
#Override // **Added line is here**
void eat() {
System.out.println("In Class B: Eating");
}

Surprising access to fields with Java anonymous class

I'm trying to better understand the concept of anonymous classes in Java. From other answers on this website, I learned that an anonymous class can access non-final fields of the enclosing class using OuterClass.this.myField.
I made the following simple test case with an interface, AnonInt, and a class AnonTest with a method foo which returns an instance of an anonymous class implementing AnonInt. Dspite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
public interface AnonInt {
void print();
}
public class AnonTest {
private int a;
public AnonTest(int a) {
this.a = a;
}
public AnonInt foo() {
return new AnonInt() {
public void print() {
System.out.println(a);
}
};
}
public static void main(String[] args) {
AnonTest at = new AnonTest(37);
AnonInt ai = at.foo();
ai.print();
}
}
Despite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
Since the reference to a is unambiguous in your context, the two expressions reference the same field.
Generally, AnonTest.this is required in a very specific context - when your method needs to access AnonTest object itself, rather than accessing one of its members. In case of your program, this is unnecessary: the compiler resolves the expression a to the object AnonTest.this.a, and passes it to System.out.println.

Private field in subclass is accessible in superclass

It is written in JLS (see section 8.3):
"A private field of a superclass might be accessible to a subclass - for example, if
both classes are members of the same class. Nevertheless, a private field is never
inherited by a subclass."
Could you give an axample of this statement?
I know that we can write:
public class MyClass {
private int x = 1;
public void testExample(MyClass m) {
m.x = 2;
}
}
Here we access private field m.x but we do not have "Super Class" - "Sub Class" here.
It's talking about nested classes - here's an example:
public class Test {
public static void main(String[] args) {
new Subclass(10).foo();
}
static class Superclass {
private int x;
Superclass(int x) {
this.x = x;
}
}
static class Subclass extends Superclass {
Subclass(int x) {
super(x);
}
public void foo() {
Superclass y = this;
System.out.println(y.x);
}
}
}
It's valid because of JLS 6.6:
Otherwise, the member or constructor is declared private, and access is permitted if and only if it occurs within the body of the top level class (ยง7.6) that encloses the declaration of the member or constructor
Here the use of x is within the body of Test, which is the top level class enclosing the declaration of x... although if you try to use x unqualified, or just this.x, that fails... precisely because x isn't actually inherited (as per the piece of spec you quoted).
Method "visibility"-as the name implies-is about where methods and variables are "visible" to the programmer. As a general contract, variables scoped within a class are always visible within the class definition, even if they are declared private and being referred to by an instantiated object (not "this") of that class.
The rules regarding visibility and encapsulation are, design-wise, meant to assist with ensuring that programmers don't accidentally access variables and methods that would break functionality if used unexpectedly. For example, you'd break the contact of how java.util.Random worked if you were to manually call
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
(Sourced from the Sun JDK source code)
However, within the scope of code that you write, it's generally considered okay to call private variables/methods on objects defined as types of that class, since it is assumed that as the programmer and writer of the code in question, you have the authority, agency, and expertise necessary to manage the code correctly.
So in general, regardless of whether the variable is declared private or not, the following code:
public class Test {
private float internalValue;
public boolean isBigger(Test t) {
return internalValue > t.internalValue;
}
}
Will always be valid.

what's the meaning of "this.this$0"?

what's the meaning of "this.this$0" in this code?
what does it stands for?
I know why we use "this" but I have no idea about "this.this$0"
class MainActivity$1 implements TextWatcher
{
public void afterTextChanged(Editable paramEditable)
{
}
public void beforeTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3)
{
}
public void onTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3)
{
this.this$0.ChangeToNumber(paramCharSequence.toString());
}
}
-----------------------or ----------------------
class MainActivity$2 implements View.OnClickListener
{
public void onClick(View paramView)
{
this.this$0.startActivity(new Intent(this.this$0, about.class));
}
}
this.this$0 it's same to Main.access$0
These mysterious symbols usually correspond to the anonymous inner classes. The Java VM doesn't know about them, only about top-level classes, so the Java compiler provides several workarounds to make inner classes to work.
Local class has implicit reference to the instance of its enclosing class,'this$0' corresponds to this reference in the decompiled code.
JVM prevents classes from accessing privates methods of other classes so the compiler generates several synthetic package-private methods like access$0 in order to access private methods of enclosing instance.
There are many others features of the Java language that are implemented with synthetic methods like generics and covariant return types.
I suggest you to check those links:
Decoding Decompiled Source Code For Android
and : Performance Tips
this$0 normally is for the parent object of a non-static inner class. E.g.,
public class Outer {
class Inner1 {
int f1 = 1;
}
static class Inner2 {
int f1 = 2;
}
public static void main(String[] args) {
Outer o = new Outer();
Outer.Inner1 i1 = o.new Inner1(); //weird but valid
Outer.Inner2 i2 = new Outer.Inner2(); //normal
//wrong: Outer.Inner1 i3 = new Outer.Inner1();
}
}
Normally we define inner class as static. i2 has only 1 field, but i1 has an extra this$0 which points to o.
There's nothing preventing you (beside decent naming conventions) from having an instance member called this$0 and then referring to it with the this keyword.
For example :
public class SomeClass
{
int this$0;
public SomeClass (int val)
{
this.this$0 = val;
}
}
The Java 1.1 Language Specification specifies that the name of a type which is a class member, when transformed into Java 1.0 code for the purpose of generating Java virtual machine bytecodes, consists of the fully qualified name of the inner class, except that each .' character following a class name is replaced by a$'. In addition, each inner class constructor receives the enclosing instance in a prepended argument. Here is how the transformed source code of the FixedStack example might look:
public class FixedStack {
... (the methods omitted here are unchanged)
public java.util.Enumeration elements() {
return new FixedStack$Enumerator(this);
}
}
class FixedStack$Enumerator implements java.util.Enumeration {
private FixedStack this$0; // saved copy of FixedStack.this
FixedStack$Enumerator(FixedStack this$0) {
this.this$0 = this$0;
this.count = this$0.top;
}
int count;
public boolean hasMoreElements() {
return count > 0;
}
public Object nextElement() {
if (count == 0)
throw new NoSuchElementException("FixedStack");
return this$0.array[--count];
}
}
Anyone who has already programmed with Java or C++ adapter classes has written code similar to this, except that the link variables must be manually defined and explicitly initialized in top-level adapter classes, whereas the Java 1.1 compiler creates them automatically for inner classes.
When the Enumerator needs to refer to the top or array fields of the enclosing instance, it indirects through a private link called this$0. The spelling of this name is a mandatory part of the transformation of inner classes to the Java 1.0 language, so that debuggers and similar tools can recognize such links easily. (Most programmers are happily unaware of such names.)
(Note: There is a limitation in some implementations of Java 1.1, under which the initialization of this$0 is delayed until after any superclass constructor is run. This means that up-level references made by a subclass method may fail if the method happens to be executed by the superclass constructor.)

Java Language Specification - Cannot understand 'BlockStatement'

I've been examining the Java Language Specification here (instead I should be out having a beer) and I am curious about what a method can contain. The specification states a method body can contain a block
MethodBody:
Block
Where a 'Block' contains 'BlockStatements'. The 'BlockStatement' rule looks like this:
BlockStatement :
LocalVariableDeclarationStatement
ClassOrInterfaceDeclaration
[Identifier :] Statement
I can understand the 'LocalVariableDeclarationStatement' which could be
[final] int x, y, z;
However, I don't get why the 'ClassOrInterfaceDeclaration' rule is there. This rule looks like:
ClassOrInterfaceDeclaration:
ModifiersOpt (ClassDeclaration | InterfaceDeclaration)
ClassDeclaration:
class Identifier [extends Type] [implements TypeList] ClassBody
InterfaceDeclaration:
interface Identifier [extends TypeList] InterfaceBody
What's going on here - You can't declare a class or interface within a block surely?
Can someone help elucidate this confusion please?
Update: I can define a class within a method, but the following won't work:
public class Foo {
public void doFoo() {
interface dooJa {
int bar();
}
}
}
The compiler complains stating "The member interface dooJa can only be defined inside a top-level class or interface"... any explanations?
Oh yes you can declare a class inside a method body. :-)
class A {
public void doIt() {
class B {}
B b = new B();
System.out.println(b.getClass());
}
}
You've made a good observation about interfaces not working anymore. The reason is you that are looking at a very old version of the grammar. It looks to be over 10 year old. Take a look the grammar for Java 6 (what you are probably testing with):
http://www.it.bton.ac.uk/staff/rnb/bosware/javaSyntax/rulesLinked.html#BlockStatement
You will see blockstatement:
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement
An example for a block with an inner class declaration:
public class Test {
static
{
class C {}
C c = new C();
}
}
Although I doubt you'll find a use case...
As others have said, you can declare a class inside a method. One use case of this is to use this as an alternative for an anonymous inner class. Anonymous inner classes have some disadvantages; for example, you can't declare a constructor in an anonymous inner class. With a class declared locally in a method, you can.
Here's a silly example that doesn't really show why you'd want to do this, but at least how you could do it.
public Runnable createTask(int a, int b) {
// Method-local class with a constructor
class Task implements Runnable {
private int x, y;
Task(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public void run() {
System.out.println(x + y);
}
}
return new Task(a, b);
}
These are called local classes. I use it occasionally, but it's not really a necessity.
Edit: a local class can be static, if it appears in a static context, for example, within a static method.
From the wording of the spec, local/inner/anno classe always means class only, not interface.

Categories

Resources