I know it is possible to do this in Java:
public class animal {...}
And then
public class dog extends animal {...}
Then you can write whatever dog methods that can access animal method.
However, I am wondering is there a way to extend methods
for example
public void generateAnimal() {...}
and then
public void generateDog() extends generateAnimal() {...}
But this is not passing the compiler.
So my question is:
Is it possible to inherit methods in Java?
You cannot extend a method the way you are describing but you can inherit the method and then call the method from the superclass as follows:
#Override
public void inheritedMethod() {
super.inheritedMethod(); // This will call method from super class
// Do subclass specific work here
}
A method is not an object by itself. Methods are meant to be called.
Yes.
public class Animal {
public void someAction() {
System.out.println("from Animal class");
}
}
public class Dog extends Animal {
public void someAction() {
super.someAction();
System.out.println("from Dog class");
}
}
public class Main {
public static void main(String[] args){
Animal dog = new Dog();
dog.someAction();
}
}
Output:
from Dog class
from Animal class
So you extend functionality of method, but better to use composition instead of inheritance.
Yes.
It was done exactly as you showed there, without the extends generateAnimal() and by changing that method name to generateAnimal().
This is called Overriding. And allows you to utilize the annotation #Override.
public class A {
public void print(){
System.out.println("Hello from A!");
}
}
public class B extends A {
#Override // This method overrides A#print()
public void print(){
System.out.println("Hello from B!");
}
}
Then, calling some action like:
B b = new B();
b.print();
Will print out:
Hello from B!
This is more widely known as Inheritance
If they are in the same class, no. However, assuming you want to run all of generateAnimal() then add your generateDog() specific code you could do this:
public void generateDog(){
generateAnimal();
///do the rest of generateDog()
}
I hope that helps.
Related
I'm trying to figure out whether implementing individual methods of a subclass in an abstract superclass, or casting is the better way to go about the following scenario.
Suppose I have an abstract class Animal which has two subclasses, Dog and Cat and a Main class where I save objects of Dog and Cat in an Animal array. The following is how I would go about using methods of the subclasses in a more generalized array.
class Main{
public static void main(String[] args){
Animal[] animalArray = new Animal[2];
animalArray[0] = new Cat();
animalArray[1] = new Dog();
for (Animal a : animalArray){
if (a.getClass().equals(Dog.class){
((Dog)a).bark();
} else {
((Cat)a).meow();
}
}
}
}
However a friend suggested that casting isn't best practice, and that I should define each method in the abstract superclass in the following way:
public abstract class Animal{
public abstract String meow(){
return null;
}
public abstract String bark();
return null;
}
}
After setting the return values of these methods to null I would need to use #Override and implement them in the respective subclasses.
Which way is better? I'm afraid the abstract class will be too large and will have methods assigned to subclasses that don't make sense (even if all they do is return null). I think by using casting I can make more precise uses of the methods.
meow() and bark() shouldn't be defined in the Animal class. These methods are specific to Cat and Dog classes.
You should define an abstract method as shown below, in the Animal class and override it in the sub classes.
public abstract class Animal {
public abstract String action() {};
}
public class Dog extends Animal {
#Override
public String action() {
//your implementation (bark)
}
}
public class Cat extends Animal {
#Override
public String action() {
//your implementation (meow)
}
}
Hope it answers your query.
So if I wanted a method to be common for 3 child classes, like this:
public void commonForAllAnimals(Animal animal) {
// this method exists in subclasses that I need
animal.foo();
// only in Dog
animal.woof();
// only in Cat
animal.meow();
}
what is the best way to go about it? I tried casting but I still end up with code duplication. Is there a simple way to at least call the 'foo()' method which would the incoming child objects have defined?
What you need to do is :
1- call foo
2- make an animal "talk"
To do that you can consider such an implementation
abstract class Animal {
abstract void foo(); // pure abstract
abstract void talk(); // pure abstract too
public void commonForAllAnimals(Animal animal) {
// this method exists in subclasses that I need
animal.foo();
// make any sub-Animal talk
animal.talk();
}
}
class Dog extends Animal {
#override
void foo() {
// make the Dog's foo
}
#override
void talk() {
this.woof();
}
void woof() {
// make a woof
}
}
class Cat extends Animal {
#override
void foo() {
// make the Cat's foo
}
#override
void talk() {
this.meow();
}
void meow() {
// make a meow
}
}
Every Animal sub-class has to implement the talk() method and considering the implementation into the sub-class it will do a woof() or a meow(). No cast needed, you just use class hierarchy.
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 a base class A, having a method "say" that calls from constructor of A. All the heritable classes uses the method "say" like it is. But one of the classes need to redefine this method. How is it possible?
For sure, I can denote base method "say" as abstract, but in that way, i have to copy the same method "say" in all the heritable classes.
If i just redefine method without denoting base one as abstract, it is not gonna be called.
public abstract class A(){
public A(){
say(); // <- wanna call this method from heritable class, if its redefined.
}
protected void say(){};
}
public class B extends A(){
public B(){
super();
}
private void say(){};
}
refactoring 1
public abstract class A(){
public A(){
// constructor methods
}
protected void say(){};
protected void executeSay(){
say();
}
}
public class B extends A(){
public B(){
super();
executeSay();
}
#Override
protected void say(){};
}
First of all one must be made clear: calling an overridable method from a constructor is a well-known antipattern. It will almost certainly break your code because the subclass method will be invoked before the subclass constructor is done and so will observe an uninitialized object. Thus I should better refrain from giving you detailed advice on Java technicalities involved in achieving this antipattern.
The only safe way to acomplish your requirement is to let the construction finish and only afterwards call an initialize-kind of method. If you want to ensure initialize is always invoked, make the constructors non-public and provide a factory method instead.
Unfortunately, Java requires quite a bit of work on your part to make this work properly.
You cannot instantiate a abstract class. That saying you have to link the abstract class reference to the concrete inherited class.
eg. A a = new B();
If that's the case, and B have redefined the say() method, then the say method in B will be called.
public class TestPad {
public static void main(String[] args) {
A a = new B();
}
}
abstract class A {
public A() {
say();
}
public void say(){
System.out.println("A");
};
}
class B extends A {
public B() {
super();
}
public void say() {
System.out.println("B");
}
}
The output will be B
public class B extends A {
public B() {
super();
}
#Override
protected void say() {
// your diffent say code
};
}
I'm not sure if you are allowed to reduce visibility to private.
Because of polymorphic method invocation, in your case the B.say() will be invoked if you override it.
But as #sanbhat commented, you need to change visibility of say() to protected.
We have a Class(say Animal), and we have an Interface(say Behave). Both Animal as well as Behave have a method with the same signature(say public void eat()).
When we try to write the body for the method eat() in a Class(say Dog) which extends Animal and implements Behave, which eat() method is actually referred to? The one in Animal or Behave. In whichever case that happens, why does it happen that way?
Edit:
I tried this scenario on Eclipse before posting this question.
An interesting part here is, even though I am implementing Behave, if I dont create an eat() method(i.e. if I dont implement Behave's inherited abstract method) inside Dog, there is no error, since I am already extending from Animal which has an eat() method.
which eat() method is actually referred to? BOTH.
Try this: if you don't override the method at all, when you call with the interface, you will get the one from the parent.
Behave b = new Dog();
System.out.println(b.eat());//this will call eat from Animal if Dog did not override.
If you override, you always get the one from the child:
Behavior b = new Dog();
Animal a = new Dog();
a.eat() and b.eat() will both refer to the eat inside of Dog class.
USE THESE CLASSES:
public class BClass {
public int add(int a, int b){
return a*b;
}
}
public interface BInterface {
public int add(int a, int b);
}
public class BChild extends BClass implements BInterface{
public static void main(String... args){
BInterface bi = new BChild();
BClass bc = new BChild();
System.out.println(bi.add(3, 5));
System.out.println(bi.add(3, 5));
}
#Override
public int add(int a, int b){
return a+b;
}
}
interface can contain only body definition of method , once you implements, it must have implementation of all defined methods. In you example
class Dog extends Animal implements Behave
{
#Override
public void eat() {...}
}
abstract class Animal{
public abstract void eat();
}
interface Behave{
void eat();
}
Here it need a body of abstract method where as it is in Main method. In other way
class DOG extends Animal implements Behave{
...
}
class Animal{
public void eat(){
...
}
}
interface Behave{
void eat();
}
Here Dog class having eat method body in its super class Animal. So it wount ask to implement body again in Animal as it is already implemented.
An interface simply defines a method that a class must provide. If we have
public class Animal{
public void eat(){
System.out.println("Om nom nom");
}
}
public class Dog extends Animal{
}
Dog now provides the eat method and can so implement Behave.
There is only one eat() method, because the designers of the language decided that the simplicity of having the method signature consist of its name and argument types was more useful than having the complexity of being able to specify that you are providing an implementation of an interface.
In Java, if the two have different semantics, provide a method which returns a Behave instance which does something else:
class Animal {
public void eat () { }
}
interface Behave {
void eat ();
}
class Dog extends Animal {
public void eat () {
// override of Animal.eat()
}
public Behave getBehave() {
return new Behave {
public void eat() {
BehaveEat();
}
};
}
private void BehaveEat() {
// effectively the implementation Behave.eat()
}
}
In other languages, you can explicitly state that a method implements a method from an interface.