Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';有一个没有抽象方法的抽象类有什么意义?_Java_Inheritance_Abstract Class - Fatal编程技术网

Java 什么';有一个没有抽象方法的抽象类有什么意义?

Java 什么';有一个没有抽象方法的抽象类有什么意义?,java,inheritance,abstract-class,Java,Inheritance,Abstract Class,可以有一个抽象类实现其所有方法——其中没有抽象方法 例如: 与使用与具体类相同的类相比,使用这样一个抽象类有什么好处(如果有的话) 我能想到的一点是,当我将它声明为抽象时,它不会被实例化。 然而,我可以通过使它具体化和它的构造函数私有化来达到同样的效果 蒂亚 //================== 编辑:我能想到的另一个用途: 它可能扩展了另一个抽象类,或者实现了一个接口而没有实现该类的抽象方法——尽管它实现了自己的所有方法。不管它值多少钱 您可以声明实现一个接口而不提供实现,然后每个子级隐

可以有一个抽象类实现其所有方法——其中没有抽象方法

例如:

与使用与具体类相同的类相比,使用这样一个抽象类有什么好处(如果有的话)

我能想到的一点是,当我将它声明为抽象时,它不会被实例化。 然而,我可以通过使它具体化和它的构造函数私有化来达到同样的效果

蒂亚

//==================

编辑:我能想到的另一个用途:

它可能扩展了另一个抽象类,或者实现了一个接口而没有实现该类的抽象方法——尽管它实现了自己的所有方法。不管它值多少钱

  • 您可以声明实现一个接口而不提供实现,然后每个子级隐式地得到扩展接口

  • 您无法创建此类的实例

  • 将来,您将为所有孩子提供通用的实现

它有一个概念上的含义:这个类的行为本身没有意义

诚然,如果没有定义良好的扩展点(即抽象方法),很难想象这样的场景,但有时它会是您问题的一个相当准确的模型

你可以有这样的东西:

public abstract class ObjectWithId {
    private final String id;

    public ObjectWithId( String id ) {
       this.id = id;
    }

    public final String getId() {
       return id;
    }
}
然后您可以扩展它来声明具有ID的不同类型的对象。这里您有一个完全指定和实现的行为,但对任何其他行为子类都没有限制

但是请注意,对同一事物建模的更简洁的方法是使用组合而不是继承

public final class ObjectWithId<T> {
    private final String id;
    private final T ob;

    public ObjectWithId( String id, T ob ) {
       this.id = id;
       this.ob = ob;
    }

    public String getId() {
       return id;
    }

    public T getObject() {
       return ob;
    }
}
public final类ObjectWithId{
私有最终字符串id;
私人期末考试;
public ObjectWithId(字符串id,T ob){
this.id=id;
this.ob=ob;
}
公共字符串getId(){
返回id;
}
公共T getObject(){
返回ob;
}
}

但是在泛型被引入(直到java版本1.4)之前,这将不是优雅的,明显比抽象类解决方案要好,因为你必须在类型安全中交易。

< P>它可以是有用的,如果你认为它是<强>实用类< /强>

,正如你指出的那样。通过使类的构造函数私有,可以防止类被实例化。除此之外,没有任何好处。支持它可能只是为了提供语言完整性。

实际的区别在于您无法创建它的实例。您必须对其进行子类化,并创建子类的实例

至于你为什么要这么做,实际上。。。我很难想出一个好的理由。您可以说,只有当有人创建了实现某个函数的子类时,该类才有意义。但是为什么不在超类中抽象这个函数呢


我不排除有人会提出一些有意义的例子,但我想不出一个。仅仅因为可以编写一段代码并且代码编译成功并不意味着它有意义。我的意思是,我可以写“总价格=商品价格*邮政编码+客户高度(单位:7.879)”,但这并不意味着这样一行代码是有意义的

我们假设您不关心抽象类的方法是实现的还是抽象的,但通过设计,它必须是抽象的,这样当有人扩展它时,他们必须添加更多的方法或重写现有的方法或按原样使用。如果他们不想重写这些方法,那么该抽象类中已经提供了默认行为

在这个抽象类中,您强制执行的唯一标准是-一个人不能实例化那个类,在使用它之前,他们必须有自己唯一的类版本

所以一般来说,实现了很少或全部方法的抽象类要比没有实现任何方法的接口好得多。这是基于这样一种假设,即您将其作为单一继承使用。

我们通常使用

public final class ObjectWithId<T> {
    private final String id;
    private final T ob;

    public ObjectWithId( String id, T ob ) {
       this.id = id;
       this.ob = ob;
    }

    public String getId() {
       return id;
    }

    public T getObject() {
       return ob;
    }
}
如果这些语句中的任何一条适用于 你的情况:

  • 您希望在几个密切相关的类之间共享代码

回答你的问题,

为什么要用具体的抽象方法声明类?

一个可能的原因是支持继承而不实际创建对象


假设有两个类,一个是抽象类,另一个是具体类

抽象类:AbsClass

abstract class AbsClass {
  int a = 5;

  //Constructor
  public AbsClass() {
    System.out.println(a);
  }

  void methodA() {
    System.out.println(a + 10);

  }

}
class ConcreteClass {
  int a = 10;

 //Made the constructor Private to prevent from creating objects of this class
  private ConcreteClass() {
    System.out.println(a);

  }

  void methodA() {
    System.out.println(a + 10);
  }
及 混凝土等级:混凝土等级

abstract class AbsClass {
  int a = 5;

  //Constructor
  public AbsClass() {
    System.out.println(a);
  }

  void methodA() {
    System.out.println(a + 10);

  }

}
class ConcreteClass {
  int a = 10;

 //Made the constructor Private to prevent from creating objects of this class
  private ConcreteClass() {
    System.out.println(a);

  }

  void methodA() {
    System.out.println(a + 10);
  }
}

上述两个类的功能应该类似(?),直到您尝试将其子类化为止

class AbsImplementer extends AbsClass {
//Works fine

}

class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible


}

考虑类似于(不确定在Java中如何称呼它):

对于公共API,您只公开一个不能被重写的公共final方法。它在其中执行一些必需的工作,并有一个可选的方法。扩展此类时,只能重写doOptional()

调用B.doSomething()将始终在继续之前打印“required”


因为doOptional()不是抽象的,所以类A不需要纯粹的代码原因来抽象。但它可能是您的特定项目所需要的。例如,始终扩展到特定子项目中的基本服务。

当从抽象基类派生的类必须具有彼此不同的行为,但该行为不能抽象为驻留在对所有类具有相同签名的方法中时,这可能非常有用。如果不同的行为需要传递不同基元类型的方法,则可能会发生无法共享签名的情况。因为它们使用基本类型,所以不能使用泛型来表示相似性