为什么我们要声明一个类是抽象的?我知道它不能实例化,但为什么给它一个特殊的关键字。即使是一个“普通”班级也可以很好地工作,并且可以很容易地进行分类。那么做一个类抽象的主要优点是什么?制作课堂摘要的主要优势是什么
回答
在抽象类中,你可以实现一些方法,并且可以抽象一些你的客户端必须实现的方法。您可以提供一些常用的功能,也可以在这里有一些继承的字段和一些骨架方法
即使我没有提出课堂摘要,我仍然可以这样做。所以,为什么要把它抽象 – TimeToCodeTheRoad 2011-01-12 18:04:06
@TimeToCodeTheRoad你怎么能把它做成抽象的? – 2011-01-12 18:05:22
声明类抽象可以防止任何代码实例化类。
这强制执行设计指南,使非叶类抽象。
它允许您稍后将抽象方法添加到您的超类(以及子类的实现),而不会影响任何现有的客户端。
即使非叶类当前没有任何抽象方法,抽象关键字仍起作用。
如果您想拥有一组继承相同逻辑功能的类,这将非常有用。 但是在同一时间,类只实现了基本逻辑,并且不包含任何实际的功能。
你应该将它看作骨架类。
例如,有一次我做这些规范的类:在另一个线程上执行命令的
控制的过程中,中继这一进程的事件。
类本身没有本身的任何功能(没有实现实际工作()函数)
所以结果是一个抽象类,可以继承,已经有一个内置的线程控制,你只需要实现work()方法即可。
如果你的类有一些默认行为,并且你希望扩展类实现一些其他行为,那么你使用抽象类。它们不能被初始化,你可以将抽象类看作是扩展类的模板。
抽象类还可以调用结果调用扩展对象方法的抽象方法。无论如何,有很多关于何时使用抽象类的讨论,何时通过接口来选择。做一个谷歌搜索,这是一个史诗般的讨论:)接口与抽象类。
如果创建它的一个实例(您将创建子类的实例)几乎毫无意义,您将声明一个类为抽象类。
public abstract class Shape {
public double calculateArea();
}
public class Square : Shape {
private double side;
double calculateArea() {
return side*side;
}
}
public class Circle: Shape {
private double radius;
double calculateArea() {
return 3.1415 * radius * radius;
}
}
public class MainClass() {
public static void Main() {
Shape myShape = new Square();
system.out.print(myShape.calculateArea());
myShape = new Circle();
}
}
这是没有意义的创造Shape
一个实例,因为它并不意味着什么具体的,它的一个抽象的概念。但是,您可以使用Shape
类型的变量,它允许您围绕常见的基本类型进行编程(尽管可能会认为在这种情况下接口可能会更好)。
抽象类可以有抽象方法和“具体”方法。
“具体”方法可以使用抽象方法,并且可以确定它们在运行时被推送(正确)。因为每个(不是抽象的)子类都必须实现它们。 (而且它不会是抽象类的实例)。
所以这都是关于保存! - 它确保想要继承抽象类的程序员必须实现抽象方法。
如果你只用一个普通的类来做到这一点,那么对应于抽象类的类将具有带有空实现的(抽象)方法,并且只有程序员必须覆盖这个方法。
当然,您可以使用抽象类的概念来进行其他思考,比如创建不可实例化的类,但这不是主要观点。
我认为你误解了抽象类的要点:它们提供了一些功能的部分实现,但不是完整的实现。
您建议抽象类是多余的,因为您可以使用public void methodname(){}
定义不完整的方法 - 这当然可以。但是,假设您的客户端继承自以这种方式定义的类,那么他们如何知道要覆盖哪些方法?如果他们忘记重写某个方法会发生什么?现在他们的派生类有一个不完整的定义 - 你不需要这个。
抽象关键字强制客户端为某些方法提供实现,否则代码甚至不会编译。换句话说,它提供了编译时保证,您使用或创建的类已完全实现。
只是一个现实生活中的例子。我有一个GUI抽象类,它是我所有GUI组件的父类。让我们称这个AbstractSuperClass。每个扩展AbstractSuperClass的组件都需要自己实现保存功能。所以关于创建我的超类抽象的好处是我可以拥有一个可以容纳我所有GUI组件的AbstractSuperClass类型数组。然后,我可以遍历该数组并调用save函数,以了解每个GUI组件都有其自己的保存方法。由于类是抽象的,它迫使我的子类提供save函数的实现。
这是特别有用的,因为当我们打开我们的API给其他程序员时,他们没有得到源代码。它们只是扩展AbstractSuperClass并且必须提供一个保存实现。
一般来说,如果在超类域类中存在继承,在子类中使用通用方法和通用实现,那么请考虑抽象类,这并不常见,但我确实使用它。
如果仅仅因为存在继承而使用抽象类,那么如果代码改变很多,就会遇到问题。这个例子在这里详细描述:Interfaces vs Abstract Classes in Java,针对电机的不同类型的域对象。其中一个需要一个双动力马达,而不是一个特定的单一类型,如太阳能供电或电池供电的马达。这需要来自两种运动类型的多个子类实现方法用于单个子类,这就是抽象类可能会变得混乱的地方。总而言之,作为一项规则,您希望使用接口定义行为(对象将执行的操作)而不是抽象类。在我看来,抽象类的主要优势在于何时来自用例的焦点在于实现层次结构和来自子类的代码重用。
- 1. ASP.NET Webforms的主要优势是什么?
- 2. 为什么在课堂上找不到主要方法?
- 3. 非OAuth解决方案的主要OAuth优势是什么?
- 4. RIA服务的主要特点和优势是什么?
- 5. GIT比SVN的主要优势是什么?
- 6. 拥有MSI安装包的主要优势是什么?
- 7. 服务器端JavaScript的主要优势是什么?
- 8. ASP.net CORE优于Asp.net的主要优势
- 9. 在aerospike中使用btree作为主要指标的优势是什么?
- 10. rspec比test :: unit有什么主要优势?
- 11. NHibernate中版本控制功能的主要优点是什么?
- 12. Scrum作为一种方法学的主要优点是什么?
- 13. 为什么我需要设置IsRequired如果它来自课堂?
- 14. 什么时候在课堂定义中需要“公开”?
- 15. EF4的主要限制是什么?
- 16. 为什么Ruby制定者需要“自我”。在课堂上的资格?
- 17. 使用摘要制作ListActivity
- 18. 制作哈希摘要轮
- 19. Git包文件名 - 什么是摘要?
- 20. 需要课堂设计帮助
- 21. 谷歌课堂课程中的“部分”字段是什么?
- 22. pathmunge优于grep的优势是什么?
- 23. Kafka优于RabbitMQ的优势是什么?
- 24. 什么是主要属性?
- 25. 什么是“主要表达”?
- 26. AngularJS指令操作需要范围摘要,为什么?
- 27. 当我的课程有一个主要课程时,为什么我的“选择不包含主要类型”?
- 28. 在课堂中是否有最重要的方法?
- 29. ES6课堂中超级(道具)的召唤是否重要?
- 30. 在codeigniter中活动记录的主要优点是什么?
@Justin:这是嘲弄吗?我想我只是想清除一个概念 – TimeToCodeTheRoad 2011-01-12 18:09:38
抱歉!我真的明白你的观点!只是试图让这个概念清除很长时间,所以写了这个。相信我,你的文章确实有帮助! – TimeToCodeTheRoad 2011-01-12 18:14:21