Sometimes, I came across some class design as follow.
abstract class animal {
public abstract void speak();
}
class dog extends animal {
#Override
public void speak() {
// Do something.
}
}
abstract class abstract_dog extends dog {
#Override
public abstract void speak();
}
I was wondering, what is the purpose of having an abstract_dog class? Why we "transform" the non-abstract speak method into abstract speak again?
In case you want to create a base class that forces people to override speak, but inherits Dog.
I agree with SLaks, and think that this would be a real life situation:
abstract class animal {
public abstract void speak();
}
class dog extends animal {
#Override
public void speak() {
// Dog says 'bark'
}
}
abstract class abstract_dog extends dog {
#Override
public abstract void speak();
}
class poodle extends abstract_dog {
#Override
public void speak() {
// poodle says 'yip yip'
}
}
class great_dane extends abstract_dog {
#Override
public void speak() {
// great dane says 'ruff ruff'
}
}
I think you would use this in the case where you want the make a new child class implement the speak method and the dog class may have other methods that the new child class would not have to implement.
Knowing more about your exact situation would help in determining if there is a better design for this scenario.
Related
To access sub-class method down-casting is needed, is there is a way to achieve this using generic without type-casting in same manner.
public class Main {
public static void main(String[] args){
Animal parrot = new Bird();
((Bird)parrot).fly();
}
}
interface Animal{
void eat();
}
class Bird implements Animal{
#Override
public void eat() {}
public void fly(){}
}
public class Main {
public static void main(String[] args){
Animal parrot = new Bird();
parrot.move();
}
}
interface Animal{
void eat();
void move();
}
class Bird implements Animal{
#Override
public void eat() {}
public void move(){fly();}
public void fly(){}
}
It could work with something like this I guess
Interfaces are meant to add methods to implemented classes without defining actual code for this method, meaning that any implemented class will definitely have the same methods but 2 implemented methods with the same name won't necessarily perform the same action.
To explain it with the current thread it would be:
interface Animal {
void move();
}
class Bird implements Animal{
public void move(){
fly();
}
}
class Dog implements Animal{
public void move(){
walk();
}
}
This way, each class will have its own definition of the move method while in main each method will be called by object.move().
This way of doing things allows to go from a code like this
for (object tmp:objList){
if(tmp.class=="Bird")
tmp.fly();
}
else if (tmp.class=="Dog"){
tmp.walk();
}
...
}
to
for (object tmp:objList){
tmp.move();
}
The parrot class should extend the Bird class, then you can call the fly method from a parrot object directly and without need to cast.
public class Parrot extends Bird{
//have some filed or method
}
I tried to implement a function in a base class which using the function of the childs (defiend as a abstract function in the base class). I think an example will demonstrate the problem in the best way.
abstract class Animal{
public void doSomthing(){
this.sound();
}
protected abstract void sound();
}
class Dog extends Animal{
#Override
protected void sound(){
System.out.println("WAF");
}
}
now when I tried to get the element in run time (by factory method which looks like: Animal factory method("Dog);) and call to the doSomthing method I got exception because it goes to the abstract method, my question is if there is any way the bypass this or another solution for this problem.
class myMain
{
public static void main(String[]args)
{
Animal doggo = new Dog(); // create object for dog
doggo.animalSound(); // call the sound for dog
}
}
class Animal
{
public void animalSound()
{
System.out.println("The animal makes a sound");
}
}
class Dog extends Animal
{
public void animalSound()
{
System.out.println("The Dog Says bow wow! ");
}
}
I do not see any problem with the approach you have mentioned in the description of your question. Maybe you are doing some other mistake. Check the following working code:
abstract class Animal {
public void doSomthing() {
sound();
}
protected abstract void sound();
}
class Dog extends Animal {
#Override
protected void sound() {
System.out.println("WAF");
}
}
class AnimalFactory {
static Animal animal;
public static Animal factoryMethod(String animalName) {
if ("Dog".equals(animalName)) {
animal = new Dog();
}
return animal;
}
}
class Main {
public static void main(String[] args) {
Animal animal = AnimalFactory.factoryMethod("Dog");
animal.sound();
}
}
Output:
WAF
The call to child class method from super class can be done.
Refer code snippet mentioned in below link:
Can a Parent call Child Class methods?
like in topic. Here's an example:
public abstract class Bird{
public abstract void eat();
public abstract void fly();
}
public interface Flyable{
public void fly();
}
public class Test extends Bird implements Flyable{
public void eat(){
System.out.println("I'm eating");
}
// And what's now?
public void fly(){
}
}
And now, there is main question. What happens. Is an error being throwed, or fly is same for interface and abstract class?
Nothing happens. Just implement your logic inside fly() and be happy.
If the methods have the same signature, everything will be fine. It is also okay to have the implementation in the abstract class or to implement a method which is specified in multiple interfaces of the class.
In Java, a method is identified by its name and its parameters. Consequently, the return type of the implemented method must be compatible with all return types of all specified methods with the same identifier. The same applies to the throw clauses. If the return type or throw clauses of the implemented method are incompatible, you will get a compilation error.
This example is not working:
public interface Flyable {
void eat();
void fly();
}
public abstract class Bird {
public int eat() {
return 500;
}
public void fly() throws StallException {
}
}
public class Eagle extends Bird implements Flyable {
}
Eagle.java, line 1: Exception StallException in throws clause of Bird.fly() is not compatible with Flyable.fly()
Eagle.java, line 1: The return types are incompatible for the inherited methods Flyable.eat(), Bird.eat()
I have a 1 Question asked in 1 Interview
class Birds {
public void fly();
public void eat();
public void sleep();
}
Have several other classes extending it like -
Sparrow extends Birds{
overriding fly();// Sparrow can have its own style to fly
overriding eat();
overriding sleep();
}
Eagle extends Birds{
overriding fly();// Eagle can have its own style to fly
}
Ostrich extends Birds {
overriding fly();// Ostrich could not fly !!!
}
How can I restrict such situation ?? Since parent class doesn't aware of its Child class here.
Birds class is extended by several classes some could override Some could not be able to override.
You need to use composition:
Define an interface called, say, Flyable which has a fly() method. Sparrow and Eagle implement that interface. Ostrich does not.
Define an interface called Living, say which has eat() and sleep() methods. All your types implement that interface.
You could point out to your interviewer that you could then have an Aeroplane() object that implements Flyable but not Living.
You can simply add FlyingBird and GroundBird classes and make them abstract.
public class Birds {
public void eat() {
// default implementation
}
public void sleep() {
// default implementation
}
}
abstract class FlyingBird extends Birds {
public abstract void fly();
}
abstract class GroundBird extends Birds {
public abstract void walk();
}
class Sparrow extends FlyingBird {
#Override
public void eat() {
// different implementation
}
#Override
public void sleep() {
// different implementation
}
#Override
public void fly() {
// some impl
}
}
class Eagle extends FlyingBird {
#Override
public void fly() {
// some impl
}
}
class Ostrich extends GroundBird {
#Override
public void walk() {
// walk implementation
}
}
I have the following system in Java:
public class Human {
public void drown(Animal animal) {
if (animal instanceOf Fish) {
return;
} else {
animal.die();
}
}
}
public abstract class LandAnimal extends Animal{...}
public class Tiger extends LandAnimal{...}
public abstract class Fish extends Animal {...}
public class Trout extends Fish {...}
I have thought of adding a method
public abstract boolean drownable() {...}
in class Animal but I don't have access to the code of Animal class.
As I know the use of instanceOf is considered bad OOP practice. How do I avoid the use of instanceOf in this case? Thanks.
The drown() method in Human should be (by the way, why do humans want to drown animals?):
public void drown(Animal animal) {
animal.drown();
}
And each Animal will know what to do, for example:
// in class Tiger
public void drown() {
die();
}
// in class Fish
public void drown() {
// do nothing, fish can't drown
}
You would declare Animal.drown() and override it in Fish, containing the appropriate 'kill code' :).
So you'd just need to call drown() on each animal and each instance will behave according to its type specific method implementation.
public class Human {
public void drown(Animal animal) {
animal.drown();
}
}
Methods can be overloaded based on their arguments. You can have two different methods:
public void drown(Fish f) {
return;
}
public void drown(LandAnimal a) {
a.drown();
}
However, it should be noted that this makes determining whether some animal will drown the responsibility of the Human class, which, as other answers show, is arguable.