【问题标题】:Why can't I have an private abstract method?为什么我不能有一个私有的抽象方法?
【发布时间】:2015-06-26 14:23:15
【问题描述】:

假设我有我的经典:

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
}

通过这些具体的实现:

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();  
     }
}

现在,我想要 Mammal 类中的一个方法,该方法可由哺乳动物的所有实例调用,例如

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

我的问题是,通过使Mammal 类不是抽象的,是否可以单独创建哺乳动物?例如

 Mammal me = new Mammal();

你不应该这样做。

但是,我确实希望有一些由所有子类调用的父类实现的公共方法,但每个都调用自己的私有方法。

【问题讨论】:

  • 这甚至不会编译。 'Mammal' 是一个普通类,所有方法都需要一个主体。除此之外:“哺乳动物”并不抽象。
  • 可以拥有一个带有方法实现的抽象类,但您无法实例化它。为什么你认为你不能?
  • @DaveNewton - 等等,你是对的,我问的原因是因为我收到了这个错误:The abstract method genRecord in type AttributeSourceTableDao can only set a visibility modifier, one of public or protected
  • @dwjohnston 想一想 - Dog 究竟会如何处理 Mammal 私有方法?
  • @jdphenix 是的,我对我遇到的编译器错误有点困惑,考虑到我无法删除它,我会更新问题。

标签: java oop inheritance abstract


【解决方案1】:

您完全可以在抽象类中实现方法:

“抽象类类似于接口。你不能实例化它们,它们可能包含声明的带有或不带有实现的混合方法。”

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

【讨论】:

    【解决方案2】:

    如果您希望它们在子类上表现不同,请将未实现的方法声明为抽象方法,并且要继承的方法使它们像普通方法一样。也使用受保护的而不是私有的,以便继承的类可以访问:

    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;
      }
    }
    

    并使用构造函数来初始化变量并实现抽象方法:

    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");
      }
    }
    

    【讨论】:

      【解决方案3】:

      回答标题中的问题(“为什么我不能有一个私有抽象方法?”):

      你不能有private abstract 方法,因为abstract 方法需要在子类中实现。但是private 方法在子类中是不可见的。

      (如果你想拥有一个只在子类中可见,而不是公开的方法,那么你需要使方法protected

      所以你永远无法实现private abstract 方法。这就是 Java 不允许它们的原因——它们没有意义。

      【讨论】:

        猜你喜欢
        • 2019-07-14
        • 2011-02-21
        • 2016-02-13
        • 2014-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-11
        相关资源
        最近更新 更多