Well, I have learned that method overriding is done in non-static methods while method hiding is done for a static method. So what is the difference between them if in method overriding the method of child class is overriding the parent class method so that only method which is of child class is executed?
While in method hiding the same thing is happening that the child class method is hiding the parent class method so that only the child class method is executing?
In the code, I provide below the output of both the program is the same so what is the difference between overriding and hiding.
The difference can be seen by the code #SMA already mentioned:
public static final void main(String... strings) {
final Child obj = new MainClass.Child();
obj.f1();
final Parent p = obj;
p.f1();
}
will lead to:
Child class
Child class
Whereas the static alternative will lead to:
Child class
Parent class
So in the overriding case the parent method can only be called from the overriding method any more. Whereas in the static case the hidden method still exists and will be called when the corresponding context (hence the parent class) is used.
(I know calling static methods through instances of the class is not a good practice, but it helps to illustrate the answer to this question.)
Related
Suppose I have these classes:
public class ChildClass extends ParentClass
{
// some class definition here
}
public abstract class ParentClass
{
public static void printClass()
{
// get the class that extends this one (and for example, print it)
}
// some class definition here
}
Lets say when calling ParentClass.printClass() I want to print the name of the class (like doing System.out.println(ParentClass.class)). When then extending ParentClass (for example like in ChildClass) and calling ChildClass.printClass(), I want it to print the name of the extending class (like doing System.out.println(ChildClass.class)). Is this somehow possible?
I've found a way to get the class from inside a static method by using MethodHandles.lookup().lookupClass(), but when using it inside of ParentClass.printClass and extending ParentClass, then calling printClass on the extending Class, I always get the class of ParentClass.
static methods are best thought of as living entirely outside of the class itself. The reason they do show up in classes is because of the design of java (the language) itself: Types aren't just types with a hierarchy, they also serve as the primary vehicle for java's namespacing system.
Types live in packages, packages are the top level namespace concept for types. So how do you refer to a method? There's only one way: Via the type system. Hence, static methods do have to be placed inside a type. But that's about where it ends.
They do not inherit, at all. When you write:
ChildClass.lookupClass()
The compiler just figures out: Right, well, you are clearly referring to the lookupClass() method in ParentClass so that is what I will compile. You can see this in action yourself by running javap -c -p MyExample. The same principle applies to non-static methods, even.
For instance methods, the runtime undoes this maneuvre: Whenever you invoke a method on any object, the runtime system will always perform dynamic dispatch; you can't opt out of this. You may write:
AbstractList<String> list = new ArrayList<String>();
list.sort(someComparator);
and you can use javap to verify that this will end up writing into the class file that the method AbstractList::sort is invoked. But, at runtime the JVM will always check what list is actually pointing at - it's an instance of ArrayList, not AbstractList (that's obvious: AbstractList is abstract; no object can ever be directly instantiated as `new AbstractList). If ArrayList has its own take on the sort method, then that will be called.
The key takeaway of all that is: Static methods do not inherit, therefore, this dynamic dispatch system is not available to them, therefore, what you want cannot be done in that fashion.
So what to do?
It feels like what you're doing is attempting to associate a hierarchy to properties that apply to the class itself. In other words, that you want there to be a hierarchical relationship between the notion of 'ParentClass's lookupClass method and ChildClass's lookupClass method - lookupClass is not a thing you ask an instance of ChildClass or ParentClass - you ask it at the notion of the these types themselves.
If you think about it for a moment, constructors are the same way. You don't 'ask' an instance of ArrayList for a new arraylist. You ask ArrayList, the concept. Both 'do not really do' inheritance and cannot be abstracted into a type hierarchy.
This is where factory classes come in.
Factory classes as a concept are just 'hierarchicalizing' staticness, by removing static from it: Create a sibling type to your class hierarchy (ParentClassFactory for example):
abstract class ParentClassFactory {
abstract ParentClass create();
abstract void printClass();
}
and then, in tandem with writing ChildClass, you also write ChildClassFactory. Generally factories have just one instance - you may want to employ the singleton pattern for this. Now you can do it just fine:
class ChildClassFactory extends ParentClassFactory {
private static final ChildClassFactory INSTANCE = new ChildClassFactory();
public static ChildClassFactory instance() { return INSTANCE; }
public ParentClass create() { return new ChildClass(); }
public void printClass() { System.out.println(ChildClass.class); }
}
// elsewhere:
// actually gets the ChildClassFactory singleton:
ParentClassFactory factory = ....;
factory.printClass(); // will print ChildClass!
Quoting #RealSkeptic:
Static methods are not inherited. The fact that you can call ChildClass.printClass() is just syntactic sugar. It actually always calls ParentClass.printClass(). So you can't do something like that with a static method, only an inheritable non-static one.
Sonar complaining about private method name in a class when we using the same name of parent private method. In code quality what is the disadvantage of defining a private method with the same name of parent private method?
Or do we need to categorize this as false positive
IMO it's because that could get confusing. Consider below, read the comment:
class Child extends Super{
public void myMethod() {
System.out.println("in child");
}
}
class Super{
public static void main(String[] args) {
Super s = new Child();
s.myMethod(); // At this point you might expect myMethod of child to be called if it'll call the Parent's since it is private.
}
private void myMethod() {
System.out.println("in super");
}
}
When you have some method in your subclass with the same name with your superclass, at the first glance, the assumption will be an override, causing confusion when it is not.
The docs mention three situations when this can happen:
The parent class method is static and the child class method is not.
The arguments or return types of the child method are in different
packages than those of the parent method.
The parent class method is
private.
And also the recommendation:
But if the intent is truly for the child class method to be different,
then the method should be renamed to prevent confusion.
So if you really want to not override the method from superclass, the recommendation is to change it to avoid confusion.
You can check an example in the RSPEC-2177 - Sonar Rule Documentation,
The decision of renaming the method or marking the ocurrence as false positive depends entirely on how the team organise their codebase, and the code convention used between the developers.
IHMO, this rule is a no sense.
If the naming makes sense for both the parent and the subclass, you will not invent a different name for one of these to make Sonar happy.
It could make code less clear and also make it less homogeneous in your base code.
Private methods are visible only inside the current class, so it is enough to make this choice safe.
I understand the purpose for the rule. However, it should not apply to abstract classes with concrete private methods.
We are using the Apache MINA library, which has several concrete private methods in CumulativeProtocolDecoder that are referenced inside their public concrete methods. If the public methods are overridden, we are forced to provide our own implementations of the private methods. It doesn't make sense to name them something else just to avoid being dressed down by Sonar.
Is it possible to have perform method overloading in different classes.
class Parent{
// Private method
private void method1(){
System.out.println("In private method of Parent class");
}
void method2(){
}
void method3(){
}
}
class Child extends Parent{
void method3(int i){
}
}
To perform overloading it is necessary to have two methods of same name and with different signature in the class. but in inheritance how does it work.
In inheritance is it true that copy of non private method is created in the child class?
In this example overloading is performed or not?
Overloading means methods with same name but different signature but not override equivalent for particular class. It's subject of class and not related to it's parent or child. Moreover, if parent has overloaded methods than child may or may not have the same behavior. Moreover, if any interface contains the overloaded signatures your class ultimately have the overloaded methods.
Note here that you have not overloaded method3(int i) with method() of parent, even more method of Child is not related to method of it's parent in your case. You can only override non-private and non-static methods of parent but you can not overload them, there is no meaning of overloading them.
Overriding - Redefining the methods in the Sub Class with out disturbing the signature. This is also called as Dynamic Binding, which will be decided during Runtime based upon the object being passed.
Overloading - Redefining the methods with in the same Class by changing the method signatures. This is also called as Static Binding, which will be decided during compile time.
Here, in your particular example, we SHOULD NOT say that the method3() is overloaded as we did not re-define method3() more than one time with in the same class.
When it comes to over - riding , there is only one rule related to access specifiers
"The subclass overridden method cannot have weaker access than super class method"
why is the child class restricted to have stronger access specifier ?
what draw back may it invite , I am guessing something to occur on design level.
let us consider the rule didn't exist , in that case
1 : parent class having weaker access say public
2 : child class having stronger access say private
so if any external class tries to access the method , it still can access from child class as it will be inherited in child class and will be available to use with object reference
please clarify.
public class A
{
public void methOne(int a)
{
// something
}
}
class B extends A
{
private void methOne(int a)
{
// something else
}
}
class C
{
public static void main(String args[])
{
new B().methOne();
// in this special case after removing the specifier rule it will execute the method from parent class.
}
}
What you have tried to do is invalid, because by extending A all instances of B must be able to act as though they were an A. For example:
A a = new A();
a.methOne(1);
Compared to:
A a = new B();
a.methOne(1);
In both cases all the code knows is that it has an A and that all As have a method called methOne. In the second case that is broken as you have tried to make the method private but A has already said that it has a method by that name available.
It works the other way around because you don't invalidate the contract. If the method was private in A and public in B then you can still use an instance of B as though it was an A, you just don't have access to that method unless you know you are working with a B.
When you re declare the method of your parent class in you child class it is method overriding which in simple terms would mean you would want the objects of your child class to call its method instead of the parents method with same name and signature. Now in child class if you have a more restrictive access specifier say by making private as in your case you are effectively telling the JVM not to call the method though it is visible to the child objects which would lead to confusion as if you have exposed only your parent class to outside world then in some of your classes if you could make this method private then JVM shouldnot allow these methods to be called if such child objects are passed .
Q. so if any external class tries to access the method , it still can access from child class as it will be inherited in child class and will be available to use with object reference
This in your above case defeats the purpose of encapsulation by making the method private. By declaring a method private you are actually trying to tell that make my parent class corresponding method not visible to outside world which is not posssible as your parent method is visible to your child class.
I have an abstract class A
I have about 10 classes that extend A
Class A has one or two static methods and it makes sense that these are static, because they belong to the 10 classes, NOT instances of them. One static method e.g. is called getAllFromX, which gets all all instances of the class from X, whatever that may be, it may be a server, well it actually is, but it doesn't matter. So you see it makes sense these methods are static and are not bound to an instance.
At the same time class A has a NON-static abstract method, each subclass overrides this method (just returns a string). I cannot make it static because static methods cannot be overridden (...).
To summarize: abstract class A has a static method and a abstract non-static method, that is overriden by the subclasses. I cannot make the second method static because it must be overriden. On the otherhand I could make the first method non-static, but it would be very ugly and bad programming style, so I'll leave it that way.
The catch? The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Is the "easiest" way to use reflection to get this done? I mean...really?
Like e.g., I get the class the static method is in:
Class<?> cl=new Object(){}.getClass().getEnclosingClass(); (a hack I found here, thank god...)
I then use getConstructor to construct an object of this subclass.
And then I use this object to call the non-static method.
Really?? Can it not be done easier? I mean that is if I want to design my program conceptually correct...
Coming from C# I don't like that (and the type erasure thing). It is just ugly. Doable but ugly. And a big stumbling block, at least for beginners. EDIT: after reading it again, I'd add: /rant end. Sorry, but I actually care.
I think what you in fact need is the following:
public class A {
public static Set<A> getAllFromX() {
...
}
}
public class B extends A {
public static Set<B> getAllFromX() {
...
}
}
public class C extends A {
public static Set<C> getAllFromX() {
...
}
}
(Just as the valueOf() and values() methods in enums, which is redefined in every Enum subclass, because static methods can't be inherited)
In this case, each class has its own static method doing whatever it wants. But your question doesn't make much sense because it says:
The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Indeed, the static method is not inherited by the subclass. Static methods are never inherited. If you define a static method foo() in A, and call
B.foo();
the compiler doesn't refuse to compile it, but it translates it to
A.foo();
So, there's no way to do in foo() something that depends on the class on which foo() is called, since it's always A.
You can always use reflection to invoke a method using class name e.g.
Object objectX = ClassX.class.newInstance();
//get your method passing argument types as second param
Method method = ClassX.class.getDeclaredMethod("methodX", null);
//invoke your method passing arguments as second param
method.invoke(objectX, null);
Since you mentioned your static method doesn't use any instance but you are using reflection to get the instance hence I am really not sure, how does it fit in your requirement though.
I think making it as an implemented method (non-static) in your abstract class is a better choice. That way you implement it once but its available in in all your 10 extending classes.
I think your problem is one of larger design. A different object should be responsible for retrieving instances of A or its subclasses. As you can see, relying on a static method to be replaced by subclasses does not work well. Without knowing more about the problem domain, it's hard to give a good answer, but I would consider something similar to the Abstract Factory pattern.
Broadly speaking: Define an abstract class, AFactory, with a method Collection getInstances(). Extend AFactory for each of the concrete subclasses of A you need to return and implement that logic in the overridden getInstances() method as appropriate. You may also provide a static method on the abstract AFactory, getFactory(Class), to get the appropriate factory subtype at runtime.