Parent class function access in Java - java

I have two child classes B and C which inherit from one parent class A. Is it possible that I can make certain functions of class A accessible in B but not in C in java?

Well i don't know a way to forbid it in the Code. But you could just override and then don'f fill them.

If what you want is to forbid to call destroyEverything() from class C:
public class A {
public void travel() {
System.out.println("Travel from A");
}
public void makePee() {
System.out.println("Call from A");
}
}
public class B extends A {
public void travel() {
super.travel();
System.out.println("Travel from B");
}
public void makePee() {
super.makePee();
System.out.println("Call from B");
}
}
Then, on C:
public class C extends A {
public void travel() {
super.travel();
System.out.println("Travel from C");
}
public void makePee(){
throw new UnsupportedOperationException("Not supported from C");
}
}
BUT, if what you want is to not inherit stuff from A, it is probably a flaw at the design of your class hierarchy and class C should not inherit from A.
Example of design flaw: Class A is Animal, class B is Beaver, and you want your class C Cadillac to inherit stuff from Animal since Animal already has the method travel.
Since maybe you don't want to inherit the method makePee (every animal urinates, but Cadillacs don't), it is better to move Cadillacs (class C) to another class hierarchy or find another class design

As per my thinking it is not possible.
Let's see the one real time example->
A Parent have a two child then both are able to access parent property .it is there no restriction on that you can not use this or you can not use this.
And if you want to do like that then you can implicitly write logic in B class also

Related

Overriding a class method in subclass Java

I have a class which has 2 methods:
class A {
public methodA();
public methodB();
}
I have two other classes B & C, which have Class A as its members:
class B {
A a;
B(Config config) {
a = config.getA();
}
}
class C {
A a;
C(Config config) {
a = config.getA();
}
}
However, in class C I want to implement a different way of method B. I guess I need to override the method, but then I will need to make class A as an abstract class. Is that correct? Is there a different way to approach this
Edit: I am not directly creating a new instance of A. I am getting it from a helper class.
I will need to make class A as an abstract class
No just make sure that methodB has not been declared to be final, since final methods cannot be overridden. You can override the method "inline" by creating a new anonymous class from the A class within your C code:
class C {
A a;
C() {
a = new A() {
#Override
public void methodB() {
// .... code goes here
}
};
}
}
Can't be done in simple way.
In Java, if you need method to be overriden, it is done in a child class. However as you get the instance of A from someone else (the config), you have no way to control what is the class instantiated by config.
There are some alternatives:
If the new methodB can be done without knowing the internal of A, you can create a wrapper of A:
class C {
static class CustomA extends A{
A a;
public CustomA (A a) { this.a = a; }
#Override
public void methodB() {
a.methodB();
a.otherMethod();
}
}
A a;
C(Config config) {
a = new CustomA(config.getA());
}
}
Another alternatives is to change your Config to allow creation of other A child classes dictated by the caller of getA(). This can be done by misc way like Reflection or initialization of already-created A instance, and etc.
Another alternative is to extract logic of methodB out to a strategy. So you can replace the strategy to whatever you want. Check out Strategy pattern in GoF design pattern.

How ambiguity is resolved automatically in multilevel inheritance in Java?

Java does not support multiple inheritance. One of the reasons is that there could be an ambiguity between methods while inheriting. For example, in the below scenario, there will be an ambiguity to which version of "LevelMethod()" should be inherited in Class “Level3”
class Level1{
public void LevelMethod(){
System.out.println("Level1 method");
}
}
class Level2{
public void LevelMethod(){
System.out.println("Level2 method");
}
}
class Level3 extends Level1,Level2{
}
But, same kind of ambiguity might occur in the following scenario through multi-level inheritance to which version of "LevelMethod()" should be inherited in
Class “Level4”.
class Level1{
public void LevelMethod(){
System.out.println("Level1 method");
}
}
class Level2 extends Level1{
public void LevelMethod(){
System.out.println("Level2 method");
}
}
class Level3 extends Level2{
public void LevelMethod(){
System.out.println("Level3 method");
}
}
class Level4 extends Level3{
}
How java is able to resolve ambiguity in multilevel inheritance, but not in multiple inheritance?
The ambiguity exists when there is no mechanism for conflict resolution.
On single inheritance, the children override the methods on their parents, the method lookup has a clear resolution with no conflicts, since there is an order.
Classic multiple inheritance does not specify conflict resolution mechanism and thus the diamond problem appears.
FYI other models like mixins specify a linearization mechanism for implicit conflict resolution, while traits require you to make explicit the algebra for conflict resolution.
The method being invoked in the inheritance hierarchy will depend on the object type. Each subclass is overriding the parent's "levelMethod".
Try with a few examples
Level1 level = new Level1();
level1.levelMethod(); //Prints "Level1 method"
Level1 level = new Level2();
level.levelMethod(); //Prints "Level2 method"
Level1 level = new Level3();
level.levelMethod(); //Prints "Level3 method"
and so on...
Objects in java are nothing but simply references. So, it doesn't matter whether two or more classes having is-a relationship have same method because it'll depend on which object calls the method, because references will be different (identified by their hashCode). in your given code, if object of Level 2 calls the method LevelMethod() then the context of class Level 2 is been referred, so evidently Java will interpret results from LevelMethod() of Level 2.
But as object of super class can refer object of child class, while calling LevelMethod() you'd need to specify of which class.
If you want to prove that references are different then execute this program:
class A{
public void cmethod(){
System.out.println("Class A");
}
}
class B extends A{
public void cmethod(){
System.out.println("Class B");
}
}
class C extends B{
public void cmethod(){
System.out.println("Class C");
}
}
class MainClass{
public static void main(String[] args){
A aObj = new A();
B bObj = new B();
C cObj = new C();
System.out.println(aObj.toString());
System.out.println(bObj.toString());
System.out.println(cObj.toString());
}
}
Explanation: If you create your own class and don't override the method toString(), then Object class will call it's default toString() method which displays Class#refHashCode (All classes are child class of class Object).

If a class is implementing two interfaces ,which one is actual the parent interface for that class in java

If a class is implementing two interfaces, which inteface is actual the parent interface for that class in Java
interface A {
void m1();
}
interface B {
void m1();
}
public class C implements A,B {
public void m1() {
System.out.println("m1 method !!!");
}
public static void main(String[] args) {
C obj = new C();
obj.m1();
((A)obj).m1();
((B)obj).m1();
A objAsA = (A)obj;
objAsA.m1();
B objAsB = (B) obj ;
objAsB.m1();
}
}
There is no such concept as "the actual parent interface" in Java. All interfaces are on equal footing as the supertypes of the class. That doesn't change even in your case where both interfaces declare the same method signature: the same method in C implements both A and B.
BTW you don't need a cast operator to accomplish an upcast:
A objAsA = obj;
objAsA.m1();
B objAsB = obj;
objAsB.m1();
parent is a concept related for extension not implementation.
From Java Java Specification
interface Fish { int getNumberOfScales(); }
interface Piano { int getNumberOfScales(); }
class Tuna implements Fish, Piano {
// You can tune a piano, but can you tuna fish?
public int getNumberOfScales() { return 91; }
}
the method getNumberOfScales in class Tuna has a name, signature, and return type that matches the method declared in interface Fish and also matches the method declared in interface Piano; it is considered to implement both.
So its considered you implement BOTH
Your question doesn't make sense. You do not have 'parent' interfaces in java.
An interface is like a contract, you 'promise' to provide the methods listed in the interface. You are getting inheritance mixed up with interfaces.
Inheritance is where one class inherits parts of another class.
Like Dog -> Husky, Dog -> Poodle
An interface is where every Animal promises to have a method called public String getSpecies() for example.
In case you want to find all the interfaces a class has look at this question.
Determining the extended interfaces of a Class
While an interface can extend other interfaces, a 'normal' class doesn't have the concept of parent interfaces.
Thank you to akhil for spotting this.
You can think of child classes as specialisations of their parents, each level being more specific.
Animal -> Dog -> Husky. However every lower level has some common functionality with its siblings. All Dogs can bark(), all Animals can move().
Now try applying this logic to interfaces and you will see that it doesn't really make sense. An interface exists only to ensure that every class has a specific ability. All animals need to breathe, regardless of what species so you can make Animals implement Breathable. Which ensures that every animal has a method breathe().
Here class C implements both the interfaces and C is A and C is B as well.
An implemenation means you need to use that method in your class. So there is no parent of it. With extendions this can be, but then there can't be 2 parents to 1 class. For example:
public static void main(String[] args){
C c = new C();
c.m1();
}
class A {
public void m1() {
System.out.println("A printing");
}
}
class B {
public void m1() {
System.out.println("B printing");
}
}
class C extends A {
public void m1() {
System.out.println("C print");
}
}
printing: "C print"
C can't extend B at the same time. But it does override the method of class A. If C did not contain the method "m1()" then the method from class A was used and the console would print: "A printing"

Instance of one class within another class

I have
public abstract class A
{
public abstract A get();
}
and
public abstract class B
{
public abstract void save(A a);
}
And bunch of different classes that extend these two classes.
And they are usually paired together. So if I have classes C, D
Then C would extend A and D would extend B and D's save function would expect C in order for it to work.
And I have controller E
public class E
{
List<B> list;
public void save(A a)
{
// how do I choose correct pair from list?
}
}
In that controller I have a list of classes that extend B.
There is a save function in E that receives extended class A as an argument.
How do I loop through all the elements in the list and figure out which class belongs to which in the pair?
Thanks to anyone for their help, I am trying to learn complex abstract classes and how to relate them.
EDIT: If I use instance of then I will have a huge if statements inside 100 classes
Let's say I have 100 classes that extend class A and 100 that extend class B.
They are paired together as I explained above.
So as a further clarification.
public class D extends B
{
public void save(A a)
{
C c = (C)a.get();
// proceed saving using c
}
}
How do I avoid doing a check for instance of inside all these classes, and know how to pair them? Is there no better way?
EDIT2: Pshemo answer is great, however I have one last question to solve.
In class E I have save function that receives class A
How do I know which class that A is linked to?
If class A is instance of C how would I know to search for instance of D in the list and call that classes' save function?
I am not sure if that is what you need, but it looks like you may want to change B class to something like
abstract class B<T extends A> {
public abstract void save(T a);
}
so now when you extend it you can specify which class should T represent, like
class D extends B<C> {
public void save(C a) {}
}

super.super.func()? - Java polymorphism

Say that I in Java have 3 classes, wheres the super one has a function named func(), I now make a subclass which overrides this, and a subclass to my subclass, now working on my sub-sub-class how will I call the 'func()' of the sub class, and the superclass?
I tried casting the 'this' "pointer", but Java 'fixes' it at runtime and calls the subsub func().
Edit:
Thanks everyone; 'Skeen is back at the drawing board'.
The best you can do is call super.func() in your subsub class, and have the func() implementation in your subclass also call super.func().
However, ask yourself, if I need knowledge not only of my parents implementation but also my grandparents implementation, do I have a design problem? Quite frankly this is tripping my "Something stinks in the fridge" instinct. You need to re-evaluate why you want to do this.
This isn't possible in Java. And btw. there aren't any pointers in Java.
I would jump on the "something in this design smells funny" train. Normally, you override a method so that it works properly for that specific subclass. If you have code in your parent class that is shared across multiple subclasses, perhaps that code could be moved to a non-overridden method so that it is readily accessible by all children/granchildren/etc.
Could you perhaps flip your design over and use more of a template method approach? (http://en.wikipedia.org/wiki/Template_method_pattern)
The notion behind Template Method is that you have some algorithm in your parent class and you can fill in the pieces that need to be class specific by polymorphic calls into your subclasses. You don't have a ton of detail in your question, but by the sounds of things, I'd really take a good look at your design and see if it makes sense.
Why don't you have func() be not inherited (call it funcBase() or whatever) and then add a wrapper func() function that calls it?
class A{
public void funcBase() {
// Base implementation
}
public void func() {
funcBase();
}
}
class B extends A{
public void func(){
super.func();
}
}
class C extends B{
public void foo(){
super.func(); // Call B's func
funcBase(); // Call A's func
}
}
I have no idea what you're trying to do, but it sounds like your class design is not appropriate for what you want, so you may want separate functions in A instead of trying to sneak your way up the ladder.
This example is the only way to call a "grandparent" super method.
class A{
public void foo(){ System.out.println("Hi"); }
}
class B extends A{
public void foo(){ super(); }
}
class C extends B{
public void foo(){ super(); }
}
This would be a different story if B doesn't override foo().
Another option would be to have a "protected helper" method in the middle class.
class D{
public void foo(){ System.out.println("Hi"); }
}
class E extends D{
public void foo(){ System.out.println("Hello"); }
protected void bar(){ super.foo(); }
}
class F extends E{
public void foo(){ super.bar(); }
}
You can access the superclass methods from within the subclass itself, e.g.
class A {
void foo() {...}
}
class B extends A {
void foo() {...}
void defaultFoo() { super.foo(); }
}
However, you really shouldn't be exposing overridden methods this way, you should write B.foo() in such a way that works fine for A and B. This is where it is a good idea to use super.foo(); like this:
class B extends A {
void foo() {
super.foo(); //call superclass implementation first
... //do stuff specific to B
}
}
Update: In response to your comment on trying to access the implementation 2 levels up, here's a way of doing it.
class A {
void foo() {
defaultFoo();
}
protected void defaultFoo() { ... }
}
class B extends A {
void foo() {...}
}
class C extends B {
void foo() {
defaultFoo();
... //do other stuff
}
}
This is a healthier pattern of coding what you want to do.
You should probably rethink how you are handling your class hierarchy if you need to place a call to a function that is defined two levels up the hierarchy. Consider writing new methods that are implemented by each subclass in a different way.

Categories