Why derived class overriding method should not be more restrictive than base class in java?
The point is that a caller who only knows about your superclass should still be able to use any instance of the subclass that it's given. Consider this situation:
public class Super
{
public void print()
{
System.out.println("Hello!");
}
}
public class Sub extends Super
{
@Override
void print() // Invalid
{
System.out.println("Package access");
}
}
Now from a different package, imagine we had:
public void printSuper(Super x)
{
x.print();
}
and we called that with:
printSuper(new Sub());
What would you expect that to do? You're overriding the method, so it should print "package access" - but then that means you're calling a package access method from a different package...
Basically, this is just one example of the Liskov Substitution Principle in action. You should be able to treat any instance of a subclass as an instance of the superclass, and it's hard to see how that fits in with making things more restrictive in a subclass.
Can a subclass override a method and have different parameters?
What you want to do is called overloading a method. It is doable and occurs often. Play with the fiddle here. Java is similar.
public class Parent
{
public virtual string HelloWorld()
{
return "Hello world";
}
public string GoodbyeWorld()
{
return "Goodbye world";
}
}
public class Child : Parent
{
// override: exact same signature, parent method must be virtual
public override string HelloWorld()
{
return "Hello World from Child";
}
// overload: same name, different order of parameter types
public string GoodbyeWorld(string name)
{
return GoodbyeWorld() + " from " + name;
}
}
public class Program
{
public static void Main()
{
var parent = new Parent();
var child = new Child();
Console.WriteLine(parent.HelloWorld());
Console.WriteLine(child.HelloWorld());
Console.WriteLine(child.GoodbyeWorld());
Console.WriteLine(child.GoodbyeWorld("Shaun"));
}
}
When overriding a method, why can I increase access but not decrease it?
It's a fundamental principle in OOP: the child class is a fully-fledged instance of the parent class, and must therefore present at least the same interface as the parent class. Making protected/public things less visible would violate this idea; you could make child classes unusable as instances of the parent class.
Overriding a method with different return types in java?
You can return a different type, as long as it's compatible with the return type of the overridden method. Compatible means: it's a subclass, sub-interface, or implementation of the class or interface returned by the overridden method.
And that's logical. If a method returns an Animal, and your derived class returns a Cow, you're not breaking the contract of the superclass method, since a Cow is an Animal. If the derived class returns a Banana, that isn't correct anymore, since a Banana is not an Animal.
Can an overriding method have a different access specifier from that in the base class?
It is possible to relax the restriction, but not to make it more restrictive:
public abstract class A {
protected void method();
}
public class B extends A {
@Override
public void method(){ // OK
}
}
public class C extends A {
@Override
private void method(){ // not allowed
}
}
Making the original method private
won't work either, since such method isn't visible in subclasses and therefore cannot be overriden.
I would recommend using interface
s to selectively expose or hide the method:
public interface WithMethod {
// other methods
void method();
}
public interface WithoutMethod {
// other methods
// no 'method()'
}
public abstract class A {
protected void method();
}
public class B extends A implements WithMethod {
@Override
public void method(){
//TODO
}
}
public class C extends B implements WithoutMethod {
// no 'method()'
}
... then only work with the instances through the interfaces.
Overloading overridden method am I overloading parent or sub-class method
You override something that is inherited, so B.a() overrides A.a(). Overriding means to redefine.
Overloading is when your class have more than one definition of the same method name (each with different argument types). In B, the name a is overloaded. There is B.a() and B.a(int x).
Some of the definitions might be inherited. So if you remove B.a(), the class B would still have a method a() since it inherits it from A. And the method name a would still be overloaded in B.
Why can't I change the return type of overriden methods (other than covariant return type)?
Let's use a simple example to explain why it doesn't make any sense to change the return type of an overridden method.
Suppose I have a Car
object:
class Car {
public String getModel() {
return "Awesome Car";
}
}
This Car
class has a method getModel()
that returns a String
.
Now, you have another class that extends Car
and overrides the getModel()
method:
class DumbCar extends Car {
@Override
public Hamburger getModel() {
return new Hamburger();
}
}
Suddenly, you have a major problem. You create a DumbCar
object and since you know that all Car
objects can tell you their model, you try to get that model:
DumbCar myCar = new DumbCar();
System.out.println(myCar.getModel());
The output is A juicy Big Mac!
Does that make any sense to you? You cannot drive a Big Mac.
Java is a heavily type-safe language. When you write a statement asking to getModel()
, you need to be absolutely, 100% positive, that the data you get back is what you were expecting. Java enforces that expectation.
Related Topics
How to Return a Button from a Function in Swiftui
Swift Memory Management: Storing Func in Var
Converting Audiobuffer to Cmsamplebuffer with Accurate Cmtime
Satisfying Expressiblebyarrayliteral Protocol
Icloud Drive Issue: "[Documentmanager] Failed to Associate Thumbnails for Picked Url"
How to Add Floating Button on Top of the Uitableview
How to Declare Protocol Property as Private
Apple Vision - Barcode Detection Doesn't Work for Barcodes with Different Colours
How to Convert Data of Int16 Audio Samples to Array of Float Audio Samples
Swift. Get Binary String from an Integer
Ckcontainer.Discoverallidentities Always Fails
Alamofire 3 Custom Encoding to Alamofire 4 Custom Encoding
How to Process an Array of Task Asynchronously with Swift Combine
Realitykit - How to Edit or Add a Lighting
What Does "Constrain to Margins" Mean in Interface Builder in Xcode 6.0.1
Does Untimeintervalnotificationtrigger Nexttriggerdate() Give the Wrong Date