简体   繁体   中英

Why can't I have an private abstract method?

Let's say I have my classic:

public abstract class Mammal {
    private int numLegs;
    private String voice;
    private Coat coat;

    public abstract void eat();

    public abstract void speak();
    public abstract void sleep();  


    private abstract void ingestFood(Food f);  //The abstract method ingestFood in type Mammal can only set a visibility modifier, one of public or protected
}

With these concrete implementations:

public class Dog extends Mammal {
     private int numLegs = 4;
     private String voice = "Woof!";
     private Coat coat = new Coat(COATTYPE.FUR, COATCOLOR.BROWN);

     @Override
     public void eat()
     { 
          Rabbit r = chaseRabbits(); 
          if (r != null) ingest(r); 
          else {
                   Garbage g = raidBin(); 
                   if (g!= null) ingest(g); 
               }


     }

     @Override
     private void ingest(Food f)
     {
         gobbleItAllUpInFiveSeconds(f); 
         stillFeelHungry(); 
     }
}

public class Human extends Mammal {
     private int numLegs = 2;
     private String voice = "Howdy!!";
     private Coat coat = new Coat(COATTYPE.SKIN, COATCOLOR.PINK);

     @Override
     public void eat()
     { 
          Food f = gotoSuperMarket();
          ingest(f); 


     }

     @Override
     private void ingest(Food f)
     {
         burp();  
     }
}

Now, I want a method in the Mammal class that is callable by all instances of the mammal, eg

public String describe() {
     return "This mammal has " + this.numLegs + "legs, a " + this.coat.getColor() + " " this.coat.getCoatType() + " and says " + this.voice;
}

My question is that, by making the Mammal class not abstract, is it possible to create a mammal by itself? Eg

 Mammal me = new Mammal();

You shouldn't be able to do this.

However, I do want to have some public methods that are implemented by the parent class that all subclasses call, but that each call their own private method.

You can totally have implemented methods in an abstract class:

"Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation."

https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Responding to the question in the title (" Why can't I have an private abstract method? ") :

You can't have a private abstract method, because abstract methods need to be implemented in subclasses. But private methods are not visible in subclasses.

(If you want to have a method that is only visible in a subclass, and not publically, then you need to make the methods protected )

So you couldn't implement a private abstract method, ever. That's why Java doesn't allow them - they wouldn't make sense.

Declare your unimplemented methods as abstract if you want them to behave differently on child classes, and the methods to be inherit leave them like a normal method. Also use protected instead of private to be accessible to inherited classes:

public abstract class Mammal
{
  protected int numLegs;
  protected String voice;
  protected Coat coat;

  abstract void eat();
  abstract void speak();
  abstract void sleep();

  public String describe()
  {
     return "This mammal has " + this.numLegs + "legs, a " 
     + this.coat.getColor() + " " this.coat.getCoatType() + " and says " + this.voice;
  }
}

And use constructors to initialize variables and implement abstract methods:

public class Dog extends Mammal
{
  public Dog(){
     this.numLegs = 4;
     this.voice = "Woof!";
     this.coat = new Coat(COATTYPE.FUR, COATCOLOR.BROWN);
  }
  void eat(){
    System.out.println("eating like a dog");
  }
  void speak(){
    System.out.println("speaking like a dog");
  }
  void sleep(){
    System.out.println("sleeping like a dog");
  }
}

public class Human extends Mammal
{
  public Human(){
     this.numLegs = 2;
     this.voice = "Howdy!!";
     this.coat = new Coat(COATTYPE.SKIN, COATCOLOR.PINK);
  }
  void eat(){
    System.out.println("eating like a human");
  }
  void speak(){
    System.out.println("speaking like a human");
  }
  void sleep(){
    System.out.println("sleeping like a human");
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM