Hiding instance variables of a class
In Java, data members are not polymorphic. This means that Parent.var
and Child.var
are two distinct variables that happen to have the same name. You're not in any sense "overriding" var
in the derived class; as you have discovered yourself, both variables can be accessed independently of one another.
The best way forward really depends on what you're trying to achieve:
- If
Parent.var
should not be visible toChild
, make itprivate
. - If
Parent.var
andChild.var
are two logically distinct variables, give them different names to avoid confusion. - If
Parent.var
andChild.var
are logically the same variable, then use one data member for them.
How to access hidden superclass instance variables from a subclass body?
AFAIK, instance variables can be only accessed once an object is
created for them.
show()
is an instance method. So, it is already operates on an instance.
Besides, as a constructor is invoked, its parent constructor is invoked.
So the constructors of all the hierarchy classes of E
that declare their own a
variable were invoked.
To refer the a
declared in the D
parent class, you can do super.a
.
Now for the remaining, it is a little tricky but you could cast this
to each parent class to be able to refer their a
variable :
public void show() {
int a = 0;
int parentD = super.a;
int parentC = ((C)this).a;
int parentB = ((B)this).a;
int parentA = ((A)this).a;
}
Note that you can do that because the a
variable declared in the parent classes uses an access modifier that allows D
instances to access to.
For example, it would not be possible if you used a private
modifier.
Instance variable hiding with inheritance
In the code below, why does println(z.x) display the value of zero?
Because it's referring to the x
field declared in A
... that's the only one that z.x
can refer to, because the compile-time type of z
is A
.
The instance of B
you've created has two fields: the one declared in A
(which has the value 0) and the one declared in B
(which has the value 2). The instance of A
you created is entirely irrelevant; it's a completely independent object.
This is good reason to:
- Make all of your fields private, drastically reducing the possibility of hiding one field with another
- Avoid hiding even where it's possible, as it causes confusion
Explain how variable hiding is working in this Java code
Yes, the B
class inherits the foo
method. But the variable x
in B
hides the x
in A
; it doesn't replace it.
This is an issue of scope. The foo
method in A
sees only the variables that are in scope. The only variable in scope is the instance variable x
in A
.
The foo
method is inherited, but not overridden, in B
. If you were to explicitly override foo
with the same exact code:
class B extends A
{
int x = 6;
@Override
void foo()
{
System.out.println(this.x);
}
}
Then the variable that would be in scope when referred to by this.x
would be B
's x
, and 6
would be printed. While the text of the method is the same, the reference is different because of scope.
Incidentally, if you really wanted to refer to A
's x
in the B
class, you can use super.x
.
Overriding member variables in Java ( Variable Hiding)
When you make a variable of the same name in a subclass, that's called hiding. The resulting subclass will now have both properties. You can access the one from the superclass with super.var
or ((SuperClass)this).var
. The variables don't even have to be of the same type; they are just two variables sharing a name, much like two overloaded methods.
Hiding instance variables in the EyeInspector or EyeExplorer
I just tried and came up with this:
Imagine this is your class:
Object subclass: #MyClass
instanceVariableNames: 'firstVariable secondVariable thirdVariable'
classVariableNames: ''
category: 'MyCategory'
Then make the following inspector class:
EyeInspector subclass: #MyClassInspector
instanceVariableNames: ''
classVariableNames: ''
category: 'MyCategory'
Add the following class method to MyClass
:
inspectorClass
^ MyClassInspector
And overwrite #addInstanceVariable:
in MyClassInspector
:
addInstancesVariable: elements
elements add: (InstanceVariableEyeElement host: self object instVarName: #firstVariable).
elements add: (InstanceVariableEyeElement host: self object instVarName: #secondVariable)
Inspect an instance of MyClass
and it shows only firstVariable
and secondVariable
but not thirdVariable
:
Very nice question!
Update: If you want an inspector that shows generally only instance variables specified in the class of an inspected object and not in superclasses of an inspected object you can use this #addInstanceVariable:
in your inspector class:
addInstancesVariable: elements
self object class instVarNames do: [:name |
elements add: (InstanceVariableEyeElement host: self object instVarName: name) ]
What does it mean to say Instance variables are not over-rided in java?
It means if you call a method in a superclass it will resolve to the overriden version in a subclass (if your instance is a subclass). However a reference to a member variable will be bound to the declaration of that variable in the class from which the call is made.
Dart: should the instance variables be private or public in a private class?
Making the class private doesn't make its members private and it doesn't make instances of that class inaccessible.
Assume
lib/private_class.dart
class Foo {
final _PrivateClass privateClass = _PrivateClass();
}
class _PrivateClass {
String publicFoo = 'foo';
String _privateBar = 'bar';
}
bin/main.dart
import 'package:so_53495089_private_field_in_private_class/private_class.dart';
main(List<String> arguments) {
final foo = Foo();
print(foo.privateClass.publicFoo);
// print(foo.privateClass._privateBar); // invalid because of ._privateBar
}
You can't declare variables or parameters of the type of a private class or extend or implement the class in another library or create an instance of that class,
but otherwise there is not much difference.
So if the field is supposed to be hidden (internal state) to users of the API, then make the field private.
How do I hide instance variables from the Ruby layer in my C-extension?
The C functions you are looking for are rb_ivar_set
and rb_ivar_get
.
rb_ivar_set
takes three arguments:
- the
VALUE
-type Ruby receiver object - the
ID
-type ivar name to assign - the
VALUE
-type Ruby right-hand-side object.
rb_ivar_get
takes two arguments:
- the
VALUE
-type Ruby receiver object - the
ID
-type ivar name to retrieve
Ruby can store instance variables internally with many kinds of ID
-type name. The only variable names made visible from the Ruby layer, though, are the ones that begin with @
, e.g. rb_intern("@foo")
. Leaving out the @
makes the instance variable inaccessible from the Ruby layer, but allows you to store and access it from the C layer.
Here is your code sample with this technique implemented.
#include "ruby.h"
static ID id_push;
static VALUE t_init(VALUE self) {
VALUE arr;
arr = rb_ary_new();
rb_ivar_set(self, rb_intern("arr"), arr); /* <-- */
return self;
}
static VALUE t_add(VALUE self, VALUE obj) {
VALUE arr;
arr = rb_ivar_get(self, rb_intern("arr")); /* <-- */
rb_funcall(arr, id_push, 1, obj);
return arr;
}
VALUE cTest;
void Init_my_test() {
cTest = rb_define_class("MyTest", rb_cObject);
rb_define_method(cTest, "initialize", t_init, 0);
rb_define_method(cTest, "add", t_add, 1); id_push = rb_intern("push");
}
Test it out! It should run like this (I didn't compile the above, there may be typos):
require 'my_test'
class MyTest
def check
return @arr
end
end
t = MyTest.new
t.add(1) #=> [1]
t.check #=> nil
The #check
method goes looking for the @arr
instance variable and comes up empty-handed. Your instance variables are safe and sound, locked up in the C layer!
Related Topics
Increase the Java Heap Size Permanently
How to Keep a User Logged into My Site for Months
Java Protected Fields VS Public Getters
_ (Underscore) Is a Reserved Keyword
Issue Using Imageio.Write Jpg File: Pink Background
How to Add Checkboxes to Jtable Swing
How to Display Legend for Pie Chart in Columns
Populating Spring @Value During Unit Test
Java Spring Boot: How to Map My App Root ("/") to Index.Html
Java Error Opening Registry Key
Concurrentmodificationexception When Adding Inside a Foreach Loop in Arraylist
How to Sort an Arraylist Using Multiple Sorting Criteria
What Is "The Inverse Side of the Association" in a Bidirectional JPA Onetomany/Manytoone Association
Log4J: Log Output of a Specific Class to a Specific Appender