I'm new to Java and I have a very basic question.
I have 2 Parent Class under the same package. Animal Abstract Class and the Machine Class.
Now, the Animal Abstract Class has a protected method. I'm aware that protected methods are accessible if the classes are under the same package.
I can access that protected method in my Machine Class, and the question is.. Is it possible to override that protected method? Without extending the Animal Class.
protected - Can be overridden by subclasses, whether they are in the same package or not
default (no access modifier) - can only be accessed or overridden if both the classes are in the same package
You can only override methods through extension.
You can override a protected method with an anonymous subclass, if you like. E.g.
public class Animal {
protected String getSound() {
return "(Silence)";
}
public void speak() {
System.out.println(getSound());
}
}
In another class:
public static void main(String ... args) {
Animal dog = new Animal() {
#Override
protected String getSound() {
return "Woof!";
}
}
dog.speak();
}
Will output:
Woof!
No , Overriding means inherit the behavior from parent class and that is not possible without extending the class.
public class PClass
{
protected boolean methodA()
{
return true;
}
}
public class CClass extends PClass
{
protected boolean methodA()
{
return false;
}
}
Run the code below to test it
public static void main(String[] args)
{
PClass pc = new CClass();
System.out.println(pc.methodA());
}
O/p=false
here we are overriding the behavior of methodA
In order to override a method you have to extend that class. That's what overriding means: having a method with the same signature as the super-class.
Overriding by definition says..
An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.
So AFAIK if you don't extend the super class there is no way to override the method.
Related
If I don't want that a method on my class can be called, I just make it private.
But if I want to allow that method to be overridden, I have to make it protected
Is it possible to have a method on an abstract class that can't be called but can be overridden? (I guess not, but is there any workaround?)
Use case:
abstract class Super {
protected void finalize() {
}
public final void doThings() {
// do stuff
finalize();
}
}
and whoever wanted to extend the class:
class Sub extends Super {
#Override
protected void finalize() {
closeSockets();
alertSomeone();
}
}
But I don't want other classes calling mySub.finalize();
Instead of overwriting a method, the sub-class may provide the super-class with a Runnable which contains the code to be executed. You could do something like this:
public class Super {
private final Runnable subClassCode;
public Super(Runnable finalizeCode) {
subClassCode = finalizeCode;
}
public final void doThings() {
// do stuff
subClassCode.run();
}
}
public class Sub extends Super {
public Sub() {
super(() -> {
// code to be executed in doThings()
});
}
}
You dont need to set the Runnable instance in the constructor. You may also give access to a protected setFinalizeCode(Runnable) method but that method could also be called by other classes within the same package as Super.
Below is my code. I have the abstract class Myabatract which has the method myMethod and I have a subclass MySubClass in which I have overridden the myMethod. In my client class
I have a method callMethod from which I want to directly call the myMethod of Myabatract class is this possible?
abstract class Myabatract {
public void myMethod() {
System.out.println("This is from Myabatract");
}
}
class MySubClass extends Myabatract {
public void myMethod() {
System.out.println("This is from MySubClass");
super.myMethod();
}
}
class Client{
public void callMethod(){
}
}
You can create an anonymous implementation of the abstract class. This is particularly easy given the fact that it does not use any abstract methods.
class Client {
public void callMethod() {
Myabatract instance = new Myabatract() { /* nothing to implement*/ };
instance.myMethod();
}
}
As a user of the MySubClass type, you have no way to call the Myabatract method because it has been overridden, unless MySubClass were to expose it. Your only recourse would be to create another method that exposed the super method from within MySubClass (or other child implementations).
It's important to note that this will not work:
class Client {
public void callMethod() {
MySubClass instance = new MySubClass() {
#Override
public void myMethod() {
super.myMethod();
}
};
instance.myMethod();
}
}
super is the non-anonymous class, MySubClass, which means nothing is actually changing. Interestingly, this can be worked around in C++ using the scope resolution operator (::).
It's also worth pointing out that you are calling super.myMethod() in your implementation of MySubClass, which does invoke the Myabatract method.
what is the need of having a rule like this in java :
"a subclass cannot weaken the accessibility of a method defined in the superclass"
If you have a class with a public method
public class Foo {
public void method() {}
}
This method is accessible and you can therefore do
Foo foo = new Foo();
foo.method();
If you add a subclass
public class Bar extends Foo {
#Override
public /* private */ void method() {}
}
If it was private, you should not be able to do
Foo bar = new Bar();
bar.method();
In this example, a Bar is a Foo, so it must be able to replace a Foo wherever one is expected.
In order to satisfy the above statement, a sub class cannot make an inheritable member less accessible. It can however make it more accessible. (This basically only applies to methods.)
What it means
The subclass method cannot have a more restrictive visibity than the superclass method.
For example, if the superclass defined
protected void a() { } // visible to package and subclasses
the subclass can override it with one of
public void a() { } // visible to all
protected void a() { } // visible to package and subclasses
but not
void a() { } // visible to package
private void a() { } // visible to itself
Why it is
Suppose the definition was
class A {
public void a() { }
}
class B extends A {
private void a() { }
}
Now, consider the following code
A instance = new B();
instance.a(); // what does this call?
On the one hand, any B has a publically accessible a method. On the other hand, the a method of a B instance is only accessible to B.
More generally, a subclass(interface) must fulfill the contract of its superclass(interface).
Visibility is only one example of this principle. Another example is that a non-abstract class must implement all methods of any interface it implements.
class Person {
public String name() {
return "rambo";
}
}
// subclass reduces visibility to private
class AnonymousPerson {
private String name() {
return "anonymous";
}
}
It's legal to call the following method with either a Person, or an AnonymousPerson as the argument. But, if the method visibility was restricted, it wouldnt' be able to call the name() method.
class Tester {
static void printPersonName(Person p) {
System.out.println(p.name());
}
}
//ok
Tester.printPersonName(new Person());
this call is legal, because a Person is a AnonymousPerson, but it would have to fail inside the method body. This violates "type safety".
Tester.printPersonName(new AnonymousPerson());
To fulfill the interface contract. Let's say I have an interface, IFlying, as:
public interface IFlying {
public void fly();
}
And I have an implementation that weakens accessibility:
public class Bird implements IFlying {
private void fly(){
System.out.println("flap flap");
}
}
I now have some library function that accepts an IFlying, and calls fly upon it. The implementation is private. What happens now? Of course, it means that the fly method cannot be accessed.
Hence, the accessibility may not be made more restrictive in an implementation.
My code:
public class PrivateOverride {
private void f() {
System.out.println("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new derived();
po.f();
}
}
class derived extends PrivateOverride {
public void f() {
System.out.println("public f()");
}
}
Output:
private f()
Why?
Because derived#f() does not override parent's class private f() method.
You could confirm it by adding #Override annotation to f() method in derived class and see that it won't compile.
Extra tips :
To override method f(), it should be inherited from parent's class, i.e. visible in your subclass, which is never the case for private methods.
Additional rules for correct method overriding are summarized in this table.
derived cannot see PrivateOverride's f() because it's private, and hence that is not an overriding, it's definition of a new method. It's always recommended to add the annotation #Override on the overridden method just to avoid such hidden problems.
Method f in PrivateOverride is declared as private. That means that it isn't overridden in derived class.
That's why you should use #Override annotation. In that case it would show you the error.
Because Private method can't be Inherited in subclass so it can't be overridden.
I have a base class and subclass. Base class has common methods and its implementation which I want to use in subclass but I want to use subclass member variable instead of superclass. I do not want to rewrite the same method in subclass. Is there a way in Java to achieve this.
You could create a protected setter on the member variable & then override the value of the super's variable within the constructor of the subclass:
class Animal {
private String voice = "Oooo";
protected void setVoice(String voice) {
this.voice = voice;
}
public void speak() {
System.out.println(this.voice);
}
}
class Dog extends Animal {
public Dog() {
setVoice("woof");
}
}
You can use a method to access the member and override it in subclasses.
Class A{
public void DoStuff(){
int aux = getResource;
/*cool things with aux*/
}
protected int getResource(){
return internal_member;
}
private int internal_member;
}
Class B extends A{
private int another_member;
#Override
public int getResource(){
return another_member;
}
}
But take into account that this will not prevent people chaging class A from using the member directly, It might be better to create a base class for the members and the getters.
Another Option, as some people outlined before is to have the data member in the base class as protected and initialize it in the subclass:
Class A{
public void DoStuff(){
/*cool things with internal_member*/
}
protected List internal_member;
A(){internal_member = /*Set here a value*/}
}
Class B extends A{
B(){internal_member = /*Set a different value here! you can even declare a member and assign it here*/}
}
You can use constructors with arguments if you need.