What I would like is to be able to create a variable with the superclass and then 'turn' it into the subclass later & be able to access the subClasses methods. It will always be defined to a subclass I just don't know which when defining.
class SuperClass {
//superclass methods
}
class SubClass1 extends SuperClass {
void subClass1method() {
//do something
}
}
class SubClass2 extends SuperClass {
void subClass2method() {
//do something different
}
}
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
a.subClass1Method(); //this is undefined it says
//a instanceof SubClass1 returns true which is what confused me
} else {
a = new SubClass2();
a.subClass2Method(); //this is undefined it says
}
}
}
I am not asking why it does this but the correct way to work around it & get the results I want.
I have looked for duplicates but could have easily missed one so please let me know.
When you don't have control of the source then there's not too much you can do besides casting (or possibly using adapters). If instanceof and casting sound familiar from your lessons then that's probably what your prof is expecting.
Here are some of your options:
// to execute those subclass specific methods without casting..
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
SubClass1 subClass1 = new SubClass1();
subClass1.subClass1Method();
superClass = subClass1;
} else {
SubClass2 subClass2 = new SubClass2();
subClass2.subClass2Method();
superClass = subClass2;
}
// ... ...
}
// using instanceof and casting
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
superClass = new SubClass1();
} else {
superClass = new SubClass2();
}
// ... ... ...
if(superClass instanceof SubClass1) {
((SubClass1) superClass).subClass1Method();
} else if(superClass instanceof SubClass2) {
((SubClass2) superClass).subClass2Method();
}
}
Below is my recommendation to achieve this goal when you have control of the source..
Rather than a new class for different behaviors you could just use composition to provide different behaviors to the one class. Note that this is especially convenient if you understand Functional Interfaces and Method References.
public class SuperClass {
private MyBehavior behavior;
public void setBehavior(MyBehavior behavior) { this.behavior = behavior; }
public void doBehavior() { this.behavior.doBehavior(); }
}
public interface MyBehavior { public void doBehavior(); }
public class MyGoodBehavior implements MyBehavior {
#Override public void doBehavior() { System.out.print("good behavior"); }
}
public class MyBadBehavior implements MyBehavior {
#Override public void doBehavior() { System.out.print("bad behavior"); }
}
public static void main(String[] args) {
SuperClass a = new SuperClass();
a.setBehavior(new MyBadBehavior());
a.doBehavior();
}
It's simple.
If you define "a" of class "SuperClass" you can only access "SuperClass" methods!
Eventually you could add abstract methods "subClass1method" and "subClass2method" to "SuperClass" and implement them in the subclasses.
When you do SuperClass a you tell the compiler that you intend to store objects of type SuperClass in the variable a. It means that you can store subclasses of SuperClass as well, but the compiler only sees a as an object of type SuperClass, regardless if you are storing a sub type.
At runtime there's no check for this, if you manage to write code that calls methods from a subclass on a, they will be called. If a is not of that particular sub class and don't implement the called method, an exception would be thrown.
But how do you force the compiler to accept that a is of the subclass type? Casting. You cast a to the subclass, then you can access methods from subclass on a. If it´s not even possible to cast an object to a subclass, you get an error at compile time.
Change your Main class to the following and it should do what you want:
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
((SubClass1)a).subClass1Method(); // Casting 'a' as SubClass1
} else {
a = new SubClass2();
((SubClass2)a).subClass2Method(); // Casting 'a' as SubClass2
}
}
}
A few examples of when casting work and don't work at compile time and runtime:
class SuperClass { }
class SubClass1 extends SuperClass { }
class SubClass2 extends SuperClass { }
class Main {
public static void main(String... args) {
SuperClass a;
SubClass1 b;
SubClass2 c;
b = new SubClass1();
a = b; // autocast to SuperClass
a = new SubClass1();
b = a; // Compile error
b = (SubClass1) a; // explicit cast
c = new SubClass2();
method(b); // works
method(c); // compiles, but will throw exception at runtime inside method
}
private static void method(SuperClass object) {
SubClass1 b = (SubClass1) object; // allowed by compiler but will throw exception at runtime in the second call, method(c)
}
}
In my project I have a superclass and two subclasses extending from it. There is a method in the superclass that is overriden differently in each subclass.
I want to know if it's possible to introduce a method (in another class) that takes object of either subclass as a parameter and calls a method overriden in one of subclasses (depending on to which subclass does the object belong).
public class Superclass{
public int method(){return 0;}
}
public class Subclass1 extends Superclass{
public int method(){return 1;}
}
public class Subclass2 extends Superclass{
public int method(){return 2;}
}
public class CallingClass{
public static int dependantCall(Superclass parameter){return parameter.method}
I want to be able to do something like
Subclass1 subclassObject = new Subclass1;
System.out.println(CallingClass.dependantCall(subclassObject));
and get output
1
That is what Polymorphism is for! Defining the Superclass as a parameter type will allow you to pass either subclass in.
For example in your other class you can define it like this:
// classes Dog and Cat extend Animal and override makeNoise()
class Owner{
playWith(Animal a){
a.makeNoise();
}
}
Now the Owner can accept owner.makeNoise(cat) and owner.makeNoise(dog)
More reading: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
Yes, it is entirely possible. Here's how that method would look like:
public <T extends Superclass> void foo(T subclassObject) {
...
}
Or:
public void foo(Superclass obj) {
...
}
Note that in the above method, you can pass subclasses' objects as well (they are covariant data types).
This is what Java does by default when you create subclases, so no need to do anything special. Each object carries it's type information at run time, and the method invoked would always be the most specific one for the object. Example:
public class Doer {
public void doSomething() {
// Body presence
};
}
public class Painter extends Doer {
#Override
public void doSomething() {
// Paint here
}
}
public class Manager extends Doer {
#Override
public void doSomething() {
// Micromanage here
}
}
// Elsewhere in your code:
public void busyness(Doer doer) {
doer.doSomething();
}
A style note: if it is possible, one should prefer using interfaces instead of base classes (base classes those should be used only if you want to share implementation between subclasses). Example with interfaces:
public interface Doer {
void doSomething();
}
public class JackOfAllTrades implements Does {
#Override
public void doSomething() {
// Do whatever necessary
}
}
// Client code stays exactly the same as above:
public void busyness(Doer doer) {
doer.doSomething();
}
Note that in Java a class can have only one base class but can implement multiple interfaces.
#Override annotations are not strictly required, but they help Java compiler to spot some errors for you (e.g. if you misprint method name).
In your example it would look like
public class CallingClass {
public static int dependantCall(Superclass parameter) {
return parameter.method();
}
}
Subclass1 subclassObject = new Subclass1();
System.out.println(CallingClass.dependantCall(subclassObject));
I have an abstract class that should implement a public field, this field is an interface or another abstract classe.
something like this:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
Now i have another specialized class Container:
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Java allow me to compile this, and i IMAGINE that the field child in SpecialContainer is automatically overloading the field child of the GenericContainer...
The questions are:
Am i right on this? The automatic 'overloading' of child will happen?
And, more important question, if i have another class like this:
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
test() will return 1 or 2? i mean the GenericContainer container field what prop1 will call, the generic or the special?
And what if the special prop1 was declared as String (yes java allow me to compile also in this case)?
Thanks!
In Java, data members/attributes are not polymorphic. Overloading means that a field will have a different value depending from which class it's accessed. The field in the subclass will hide the field in the super-class, but both exists. The fields are invoked based on reference types, while methods are used of actual object. You can try it yourself.
It's called, variable hiding/shadowing, for more details look on here
It isn't overriding anything, you're just hiding the original field at the current class scope. If you use a variable with the subtype you will still be able to access the original property. Example:
abstract class GenericContainer {
public GenericChild child;
}
abstract class GenericChild {
public int prop1=1 ;
}
class SpecialChild extends GenericChild {
public int prop1=2;
}
class SpecialContainer extends GenericContainer {
public SpecialChild child;
}
public class Main {
public static void main( String ... args ) {
GenericContainer container = new SpecialContainer();
container.child = new SpecialChild();
System.out.println( container.child.prop1 );
SpecialChild child = (SpecialChild) container.child;
System.out.println( child.prop1 );
}
}
This prints 1 and then 2.
From SpecialChild you would also be able to go up one level using super:
class SpecialChild extends GenericChild {
public int prop1=2;
public int getOriginalProp1() {
return super.prop1;
}
}
Regarding
....and i IMAGINE that the field "child" in SpecialContainer is automatically overloading the field 'child' of the GenericContainer...
No. Fields don't get overridden, only methods do.
This is one reason why use of (overridable) getter and setter methods are preferred to direct access to fields. Your fields should almost all be private.
As for your design, there's no need for your SpecialContainer class to have a SpecialChild field, but instead the SpecialChild object should be placed in the GenericChild field.
Why nobody is observing that program will throw NullPointerException.
subclass's field with same name will hide super class's field. There is no overriding with field. Overriding is only possible with methods.
Original Code by Author:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extend GenericChild {
public int prop1=2;
}
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
Java allow me to compile this, and i IMAGINE that the field "child" in
SpecialContainer is automatically overloading the field 'child' of the
GenericContainer...
Firstly, Inheritence doesn't apply to variables. Fields(Insatnce variables) are not overridden in your sub-class.they are only visible in your subclass if they are marked with either public, protected or default.
To answer your question it maintains both instances. And depending on how you refer to the container (either through the abstract or the impl) determines which variable you are referring to.
public class Test {
public abstract class Container{
public Generic gen = new Generic();
}
public class ContainerImpl extends Container{
public GenericImpl gen = new GenericImpl();
}
public class Generic{
public int prop = 0;
}
public class GenericImpl extends Generic{
public int prop = 1;
}
public Test(){
Container c = new ContainerImpl();
System.out.println(c.gen.prop); // Outputs "0"
System.out.println(((ContainerImpl)c).gen.prop); // Output "1"
}
public static void main(String[] args) {
new Test();
}
}
The bigger question at hand is, why would you design something like this? I'm assuming you are asking from a theoretical perspective.
My 2 cents, this isn't great OO design. You would be better off making the public variables private and assigning their values through a constructor or property setter. As-is, it will lead to unexpected results in your code.
I need to refactor class extracting abstract superclass.
E.g.
UpperClass {
NestedClass {
UpperClass.this.someMethod();
}
}
Like:
AbstractUpperClass {
NestedClass {
?????.this.someMethod();
}
}
After I plan inherit AbstractUpperClass in 2 classes UpperClass1 and UpperClass2.
But I don't know how to refactor this inner class because it inovokes method of enclosing class. Does it possible?
Thanks.
The trick here is knowing how the inner class works. It's essentially just a "normal", static class, but whose constructor implicitly gets a reference to the enclosing class. So, this:
public class TopLevel {
public void go() {
new Inner().bar();
}
public void foo() { }
public class Inner {
public void bar() {
TopLevel.this.foo();
}
}
}
is equivalent to this:
public class TopLevel {
public void go() {
new Inner(this).bar(); // explicitly passing in "this"
}
public void foo() { }
public static class Inner {
private final TopLevel parent; // note that we have this new field
public Inner(TopLevel parent) { // note this new constructor
this.parent = parent;
}
public void bar() { // we use the explicit reference instead
parent.foo(); // of the implicit TopLevel.this
}
}
}
So, with all that said, the way to refactor your inner class to be a top-level class is to add an explicit field referencing the UpperClass instance, and passing this reference into the NestedClass constructor. In other words, be like that second code snippet instead of the first.
This is a question I was asked in an interview: I have class A with private members and Class B extends A. I know private members of a class cannot be accessed, but the question is: I need to access private members of class A from class B, rather than create variables with the same value in class B.
The interviewer was either testing your knowledge of access modifiers, or your approach to changing existing classes, or both.
I would have listed them (public, private, protected, package private) with an explanation of each. Then gone on to say that class A would need to be modified to allow access to those members from class B, either by adding setters and getters, or by changing the access modifiers of the members. Or class B could use reflection. Finally, talk about the pros and cons of each approach.
Reflection? Omitting imports, this should work:
public class A {
private int ii = 23;
}
public class B extends A {
private void readPrivateSuperClassField() throws Exception {
Class<?> clazz = getClass().getSuperclass();
Field field = clazz.getDeclaredField("ii");
field.setAccessible(true);
System.out.println(field.getInt(this));
}
public static void main(String[] args) throws Exception {
new B().readPrivateSuperClassField();
}
}
It'll not work if you do something like that before the of invocation readPrivateSuperClassField();:
System.setSecurityManager(new SecurityManager() {
#Override
public void checkMemberAccess(Class<?> clazz, int which) {
if (clazz.equals(A.class)) {
throw new SecurityException();
} else {
super.checkMemberAccess(clazz, which);
}
}
});
And there are other conditions under which the Reflection approach won't work. See the API docs for SecurityManager and AccessibleObject for more info. Thanks to CPerkins for pointing that out.
I hope they were just testing your knowledge, not looking for a real application of this stuff ;-) Although I think an ugly hack like this above can be legit in certain edge cases.
The architecture is broken. Private members are private because you do not want them accessed outside the class and friends.
You can use friend hacks, accessors, promote the member, or #define private public (heh). But these are all short term solutions - you will probably have to revisit the broken architecture at some stage.
By using public accessors (getters & setters) of A's privates members ...
You cannot access private members from the parent class. You have make it protected or have protected/public method that has access to them.
EDIT : It is true you can use reflection. But that is not usual and not good idea to break encapsulation.
A nested class can access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
public class SuperClass
{
private int a = 10;
public void makeInner()
{
SubClass in = new SubClass();
in.inner();
}
class SubClass
{
public void inner()
{
System.out.println("Super a is " + a);
}
}
public static void main(String[] args)
{
SuperClass.SubClass s = new SuperClass().new SubClass();
s.inner();
}
}
If I'm understanding the question correctly, you could change private to protected. Protected variables are accessible to subclasses but behave like private variables otherwise.
By using setters and getters u can access it
From JLS §8.3. Field Declarations:
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.
I write the example code:
public class Outer
{
class InnerA
{
private String text;
}
class InnerB extends InnerA
{
public void setText(String text)
{
InnerA innerA = this;
innerA.text = text;
}
public String getText()
{
return ((InnerA) this).text;
}
}
public static void main(String[] args)
{
final InnerB innerB = new Outer().new InnerB();
innerB.setText("hello world");
System.out.println(innerB.getText());
}
}
The explanation of the accessibility of InnerA.text is here JLS §6.6.1. Determining Accessibility:
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.
You can use the setters and getters of class A. Which gives same feeling as if You are using a class A's object.
Have you thought about making them protected ? Just to be sure you are aware of this option, if you are then pardon me for bringing up this trivia ;)
Private members cant be accessed in derived class
If you want to access means you can use getter and setter methods.
class A
{
private int a;
void setA(int a)
{
this.a=a;
}
int getA()
{
return a;
}
}
Class B extends A
{
public static void main(String[] arg)
{
B obj= new B();
obj.setA(10);
System.out.println("The value of A is:"+obj.getA());
}
}
Private will be hidden until you have been given the right access to it. For instance Getters or setters by the programmer who wrote the Parent. If they are not visible by that either then accept the fact that they are just private and not accessible to you. Why exactly you want to do that??
I don't know about Java, but in some languages nested types can do this:
class A {
private string someField;
class B : A {
void Foo() {
someField = "abc";
}
}
}
Otherwise, use an accessor method or a protected field (although they are often abused).
A private member is accessible in subclass in a way that you cannot change the variable, but you are able to access the variable as read only.
Obviously, making them protected, or adding setters/getters is the preferred technique. Reflection is a desperation option.
Just to show off to the interviewer, IF "access" means read access, and IF Class A generates XML or JSON etc., you could serialize A and parse the interesting fields.
Class A
{
private int i;
int getValue()
{
return i;
}
}
class B extends A
{
void getvalue2()
{
A a1= new A();
sop(a1.getValue());
}
}
To access private variables of parent class in subclass you can use protected or add getters and setters to private variables in parent class..
You can't access directly any private variables of a class from outside directly.
You can access private member's using getter and setter.
Ways to access the superclass private members in subclass :
If you want package access just change the private fields to protected. It allows access to same package subclass.
If you have private fields then just provide some Accessor Methods(getters) and you can access them in your subclass.
You can also use inner class e.g
public class PrivateInnerClassAccess {
private int value=20;
class InnerClass {
public void accessPrivateFields() {
System.out.println("Value of private field : " + value);
}
}
public static void main(String arr[])
{
PrivateInnerClassAccess access = new PrivateInnerClassAccess();
PrivateInnerClassAccess.InnerClass innerClass = access.new InnerClass();
innerClass.accessPrivateFields();
}
}
4 .You can also use Reflection e.g
public class A {
private int value;
public A(int value)
{
this.value = value;
}
}
public class B {
public void accessPrivateA()throws Exception
{
A a = new A(10);
Field privateFields = A.class.getDeclaredField("value");
privateFields.setAccessible(true);
Integer value = (Integer)privateFields.get(a);
System.out.println("Value of private field is :"+value);
}
public static void main(String arr[]) throws Exception
{
B b = new B();
b.accessPrivateA();
}
}
You can use Accessors (getter and setter method) in your Code.
By using setter method you can use else with the help of refection you can use private member of class by setting that member say a -
take a from class
and set a.setAccessible(true);
You may want to change it to protected.
Kindly refer this
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
If this is something you have to do at any cost just for the heck of doing it you can use reflection. It will give you list of all the variables defined in the class- be it public, private or protected. This surely has its overhead but yes, it is something which will let you use private variables. With this, you can use it in any of the class. It does not have to be only a subclass
Please refer to the example below. This may have some compilation issues but you can get the basic idea and it works
private void getPropertiesFromPrivateClass(){
Field[] privateVariablesArray = PrivateClassName.getClass().getDeclaredFields();
Set<String> propertySet = new HashSet<String>();
Object propertyValue;
if(privateVariablesArray.length >0){
for(Field propertyVariable :privateVariablesArray){
try {
if (propertyVariable.getType() == String.class){
propertyVariable.setAccessible(true);
propertyValue = propertyVariable.get(envtHelper);
System.out.println("propertyValue");
}
} catch (IllegalArgumentException illegalArgumentException) {
illegalArgumentException.printStackTrace();
} catch (IllegalAccessException illegalAccessException) {
illegalAccessException.printStackTrace();
}
}
Hope this be of some help.
Happy Learning :)
Below is the example for accessing the private members of superclass in the object of subclass.
I am using constructors to do the same.
Below is the superclass Fruit
public class Fruit {
private String type;
public Fruit() {
}
public Fruit(String type) {
super();
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Below is subclass Guava which is inheriting from Fruit
public class Guava extends Fruit{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Guava(String name,String type) {
super(type);
this.name=name;
}
}
Below is the main function where we are creating an object of subclass and also displaying the member of superclass.
public class Main {
public static void main(String[] args) {
Guava G1=new Guava("kanpuria", "red");
System.out.println(G1.getName()+" "+G1.getType());
}
}
Note that a private field of a superclass might be accessible to a subclass (for example,if both classes are memebers of the same class),Nevertheless,a private field is never inherited
by a subclass
Simple!!!
public class A{
private String a;
private String b;
//getter and setter are here
}
public class B extends A{
public B(String a, String b){ //constructor
super(a,b)//from here you got access with private variable of class A
}
}
thanks
Directly we can't access it. but Using Setter and Getter we can access,
Code is :
class AccessPrivate1 {
private int a=10; //private integer
private int b=15;
int getValueofA()
{
return this.a;
}
int getValueofB()
{
return this.b;
}
}
public class AccessPrivate{
public static void main(String args[])
{
AccessPrivate1 obj=new AccessPrivate1();
System.out.println(obj.getValueofA()); //getting the value of private integer of class AccessPrivate1
System.out.println(obj.getValueofB()); //getting the value of private integer of class AccessPrivate1
}
}
Modifiers are keywords that you add to those definitions to change their meanings. The Java language has a wide variety of modifiers, including the following:
Java Access Modifiers
Non Access Modifiers
To use a modifier, you include its keyword in the definition of a class, method, or variable. The modifier precedes the rest of the statement.
There is more information here:
http://tutorialcorejava.blogspot.in/p/java-modifier-types.html