This is a simple example of inheritance where there is a shadowed variable x.
class A{
int x=1;
}
class B extends A{
int x=2;
}
class C extends B{
int x=3;
int y;
}
How can I reference the shadowed variable x of class A in class C?(I want something like y=super.super.x; that works well.)
Not as hard as you might think. (While I strongly encourage avoiding this situation,) if you have a class C that inherits from class B, which in turn inherits from class A, all of which implement a public field x, then using super is usually the wrong way to go about it.
Instead, given class C, try this:
((A)this).x; //don't forget the parentheses!
that will give you the value of x for A. Also,
super.x == ((B)this).x;
which is generally why, for single steps, we usually just use super.
Hopefully that helps.
To my knowledge, there is no way to achieve this the way you imagine. Your best bet would be to implement an access method in your class B:
class B extends A{
int x=2;
protected int getXFromA() {
return super.x;
}
}
This way you would be able to access the value of x as defined in class A from class C.
I would be very interested in your use case, though. Considering object oriented design, what reason could there be to directly access A's members from C? If this is the case, from an OOP perspective, C could not really be considered a proper subclass of B anymore.
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class C extends B {
int x = 3;
int y = ((A) this).x;
}
Note that shadowing is generally discouraged due to the confusion it can cause.
Related
I have a problem with my abstract class, I have an app for about 2000 users and many make calls at the same time to different classes, those classes share an abstract class
class A extends B{
//Code
}
The inconvenience arises when in my abstract class I receive parameters to some of my methods that in this case all classes call these methods.
class abstract B {
public int getResult(int b){
return b+1;
}
}
class C extends B {
public int getValue(int a){
int b = getResult(a);
int c = b * 2 / 4;
return c + 150;
}
}
When several people in parallel enter the class 'C' and pass different parameters to the method getResult ends up mixing the data sent and returns erroneous data in the execution.
The option that I have found is to implement the getResult method in each class, but that makes me repeat code in each class and there are about 200 classes that implement that abstract class
I've read that with encapsulation I can avoid that, but I don't know if that's the option since I haven't worked on it.
I have used the synchronized but it has created many bottlenecks and response times have increased.
I think you need use synchronized in your getValue method to manage parallel access to yout method. Maybe this article can help you, have a simple example too: https://dzone.com/articles/java-concurrency-synchronization#:~:text=the%20credit%20method
Note B class must have _"abstract" keyword before class.
Add "synchronized" in your getValue method
This way:
abstract class B {
public int getResult(int b){
return b+1;
}
}
class C extends B {
public synchronized int getValue(int a){
int b = getResult(a);
int c = b * 2 / 4;
return c + 150;
}
}
Consider class A
class A {
int i;
int j;
int k;
}
and here is the class B
class B {
int a;
int b;
int c;
}
I was wondering if java has any such ting which allows to write/define our own custom casting logic.
For e.g.
to cast class B's object into class A's object where
i -> a // i pointing to value of a
j -> b // j pointing to value of b
k -> c // k pointing to value of c
(I can customize the logic to whatever i wish)
I have a few heavy weight objects to "cast" into some other classes to use and i do not want to write a converter method for this.
(casting operates only on the object in consideration and does not create another object)
any thoughts/suggestions for this ?
Thanks in Anticipation !
You can use the frameworks like ModelMapper (documentation) to define your maping logic and use it to convert object from one type to object of another type. E.g. this is how the configuration would be:
//Model Classes
class A{
int a;
}
class B{
int d;
}
//Mappings
PropertyMap<A, B> map = new PropertyMap<A, B>() {
protected void configure() {
map(source.a, destination.d);
}
};
//Test Program
public static void main(String[] args) throws Exception {
ModelMapper mapper = new ModelMapper();
PropertyMap<A, B> map = new PropertyMap<A, B>() {
protected void configure() {
map(source.a, destination.d);
}
};
mapper.addMappings(map);
A a = new A();
a.a = 10;
B b = mapper.map(a, B.class);
System.out.println(b.d);
}
This defeats the safety purposes of Java for two reasons.
Let's consider an updated version of your class code.
class A {
int i;
int j;
int k;
int l;
}
class B {
int a;
int b;
int c;
}
Now imagine what would happen if you did something like this, assuming the classes were written right above: (Warning:code will not compile)
public static void main(String[] args)
{
B classTwo = new B();
A classOne = (A) classTwo;
classOne.l = 3; // <-- what would happen?
}
As you can see, it won't work, because creating an instance of B will not allocate the variabls properly. This is why Java does not permit casting like that.
What Java does permit is converting between superclasses and subclasses.
For example:
class Fruit {
int i;
}
class Apple extends Fruit {
int j;
}
And now inside the main function:
Fruit f = new Fruit();
Apple a = (Apple)f; // this compiles, but will raise a ClassCastException
You'll ask, why does it raise a ClassCastException? Apple extends Fruit.
Yes, Apple extends Fruit. But, Fruit does not allocate memory for the j variable.
What is allowed is the other way around, casting an Apple to a Fruit, because all Apples have properties of Fruits (even in real life).
If you want to use your idea of casting, you could try an interface.
interface C {
public int getVarOne();
public int getVarTwo();
// NO variables here, only functions
}
Any class which implements (not extends) an interface must also implement all of the methods defined in it.
Once you've implemented the interface, the behavior is similar to casting to a superclass. There are also other uses for interfaces, but that is beyond the scope of this question.
No. There's no such thing as unions known from C. You cannot modify the memory directly in JVM. That's the point of Java. It sacrifices some potential for tricks, but in the end the code tends to be less buggy and easier to maintain than the code written in C.
If your concern is memory consumption caused by copying, you can convert A and B into interfaces. The interfaces should expose getters and setters. For example: int getI() and int getA(). Then you can introduce a class implementing both of them.
The indirection caused by the interface calls will have some performance cost, but in many cases, it won't be noticable.
Is there some object oriented thing that you can call some methods from certain classes, but not all of them? Is there something like that which is similiar to protected?
Say you have a method void foo() and you want it to be available to the programmer in a few types of classes (perhaps something like using Type variables (to specify: T type). Now, perhaps is there some way, without inheriting the class with foo() in it, or making an interface, to specify which classes or types of classes have access to that method?
I would guess this could be like multiple-inheritance and polymorphism? But I still want only the class and certain classes to access the method without changing the visibility of the method. I want the visibility to be class-specific.
Here is an example:
class A sees foo() as private, but only that class sees it as private.
class B sees foo() as public/protected, but only that class sees it as public.
The method type would be default.
I guess what is easier to ask and answer to is: "Is there class-specific visibility?"
There is something like you are asking for in C++, it is called friend classes. Nevertheless, that concept is not supported by Java:
'Friends' equivalent for Java?
A second option is to use code reflection to access a class private members but it isn't such a clean solution and only works for protected elements:
public class C1 {
public C1()
{
x = "Hello Word!";
}
protected String x;
}
At a different class's method:
String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);
EDIT: After making a little bit of research I found it is possible even to access private members:
Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);
No, there's nothing like that in Java.
The closest you've got is putting classes within the same package, at which point they have access to any members which don't specify any access modifier. You can't specify particular classes though.
Another option which is appropriate in some cases is to use nested classes:
class Outer {
private static class Inner {
}
}
Here Outer and Inner have access to each other's private members.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
thats your lot, there are not any other access modifiers.
With a little sleight of hand you can make one class seem to be two different classes:
// An interface.
interface A {
public void a ();
}
// Another interface.
interface B {
public void b ();
}
// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
public void a () {
}
public void b () {
}
}
// Pick either implementation from C and tell the world about it.
class D extends C implements A {
// Do nothing - already done by C.
}
class E extends C implements B {
// Do nothing - already done by C.
}
public void test() {
A d = new D();
B e = new E();
}
Here D and E are actually identically functioned objects because they are both actually Cs. However, as they are created they are made to seem to be A or B which are two different interfaces.
Unfortunately we cannot hide the fact that they both extend C but a little further sleight of hand and we can do that too with a Factory.
// Hide the guts of it all in a factory.
static class Factory {
// Make sure you MUST use the factory methods.
private Factory () {
}
// Construct an A.
public static A newA () {
return new D();
}
// Construct a B.
public static B newB () {
return new E();
}
}
Let say I have the following java classes:
Class A:
public class A {
private int x;
public A(int x){
this.x = x;
}
public static void main(String[] args) {
A a = new A(1);
B b = new B(1,2);
System.out.println((A)b.x);
}
}
Class B:
public class B extends A {
public int y;
public B(int x, int y){
super(x);
this.y = y;
}
}
Why does the compiler marks the access to x on this line
System.out.println((A)b.x);
as an error, even though I'm trying to access x from the class in which it is defined?
Is it because of:
1. the use of polymorphism?
2. the use of a static method?
3. the use of the main method?
You need to make it ((A)b).x to properly type cast it
Note : You are trying to type cast the property x to type A. That's the error!
int x is private therefore it can't be reached from outside of the scope of the class. You could mark it as protected. This way it will still have limited scope. Classes that extend A will be able to access the variable freely.
This is because the dot operator has precedence over the cast operator. This will work, because it forces the cast operator to be applied before the dot operator:
System.out.println(((A)b).x);
Demo on ideone.
When you write (A)b.x, the compiler try to cast b.x into A, but x is an int
Moreover, you don't need to cast b into A and you can't access b.x because x is a private field.
You may need a getter for this, like b.getX()
You have follwing issues
Compiler will show "Field not visible" Error,Because you trying to access private method of parent class
Syntactically. operator has precedence over cast operator
And another impotent thing is that No need to cast a child object to parent to access parent specific members, Because they are already inherited to the child, Here the member you are accessing is private ,which is not inherited. Even if you cast to parent you cant access private members using child object.
Because you are trying to cast an int into A. You need to wrap the cast around the object and then call .x.
Your call is equivalent to (A)(b.x), when it should be ((A)b).x.
public static void main(String[] args) {
A a = new A(1);
B b = new B(1,2);
System.out.println(((A)b).x);
}
Basically, two issues exist here.
One being that int x is private so it cannot be accessed from the sub-class.
Now even if you change the access criteria of int x to publicor protected; the code will still not work because (A)b.x will try to typecast an integer (read x) to an object (read A). Instead of this, you should use ((A)b).x
G'day people,
I am feeling embarrass by asking such a naive question. But I can't understand one thing,
I have Inheritance structure like this,
B extends A, code I have wrote is as below,
Class A
public class A{
private int pos = 0;
public A(){
this.pos = 12;
}
public int getPos(){
return this.pos;
}
}
Class B
public class B extends A{
int spec = 15;
public B(){
super();
}
public int getSpec(){
return this.spec;
}
}
And I have one more class to test, Which will get us to my question.
Class Test
import java.util.*;
public class Test{
public static void main(String[] args){
B a = new B();
ArrayList<A> c = new ArrayList<A>();
c.add(a);
System.out.println(c.get(0).getPos());
System.out.println(c.get(0).getSpec());
}
}
Question : Now I am creating an instance of B, Which means I can access to my parent class's method getPos() and B's own method getSpec(). But if I create ArrayList with type A(...B is type A too, as it extends A...) and add my B's instance it losses it's ability to access it's own method. What am I doing wrong? Does ArrayList implementation is casting my B to A internally?
Note : My basic understanding of inheritance is parent cannot access
child's method except they are protected. But Child can access their
parent class's method.
There's no casting involved. What you're doing is no different from this:
A bAsA = new B():
While the object referred by bAsA is truly a B object, it is held by an A variable and thus only A methods are available (unless you explicitly cast it as a B variable).
Since your ArrayList is an ArrayList of A, each item in the ArrayList is treated as an A variable and only A methods are available.
Does ArrayList implementation is casting my B to A internally?
No. There is no "internal casting." You, the programmer, have told the compiler it's a list of A.
You have declared the List as List<A>, which you can read as "a list of A". Since all B are A, you can add any B to a List<A>. On retrieval, however, you're only guaranteed to get back an A, not a B — because it's a List<A>, remember — so the compiler treats everything that comes out of the list as an A, even if (at runtime) it's an instance of B.
In addition to the answers provided by #Matt Ball and #Hovercraft Full Of Eels, you can avoid having to explicitly cast by declaring methods implemented by the subclass as abstract methods in the superclass.
public abstract class A{
.
.
public abstract int getSpec();
}
EDIT-
As mentioned by #Kublai Khan, it is necessary to then make the superclass an abstract class.