- 浏览: 369093 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (511)
- AgileMethodology (4)
- RDBMS (32)
- NoSQL (16)
- Java (27)
- Python (28)
- Maven (15)
- Linux (27)
- CommonUtils (13)
- IDE (8)
- JavaScript (17)
- jQuery (2)
- OSGi (2)
- JavaWeb (5)
- Spring (37)
- Struts2 (3)
- ORM (13)
- Ant (1)
- apache-tiles (1)
- FreeMarker (2)
- JSON (8)
- XML (1)
- JUnit (3)
- Lucene (1)
- Web Service (9)
- Design Pattern (13)
- Algorithm (21)
- JVM (14)
- Hadoop (16)
- Spark (5)
- Scala (31)
- Git (4)
- Server (3)
- Node.js (18)
- Concurrent (42)
- Lock (9)
- Collections (3)
- Network (11)
- MicroService (7)
- Docker (13)
- FP (20)
- spring.io (2)
- ELK (1)
- Kafka (5)
最新评论
The classic example in OOP is the “shape” example. This is commonly used because it is easy to visualize, but unfortunately it can confuse novice programmers into thinking that OOP is just for graphics programming, which is of course not the case.
The shape example has a base class called Shape and various derived types: Circle, Square, Triangle, etc. The reason the example works so well is that it’s easy to say “a circle is a type of shape” and be understood. The inheritance diagram shows the relationships:
The upcast could occur in a statement as simple as:
Shape s = new Circle();
Here, a Circle object is created, and the resulting reference is immediately assigned to a Shape, which would seem to be an error (assigning one type to another); and yet it’s fine because a Circle is a Shape by inheritance. So the compiler agrees with the statement and doesn’t issue an error message.
Suppose you call one of the base-class methods (that have been overridden in the derived classes):
s.draw();
Again, you might expect that Shape’s draw( ) is called because this is, after all, a Shape reference—so how could the compiler know to do anything else? And yet the proper Circle.draw( ) is called because of late binding (polymorphism).
The following example puts it a slightly different way. First, let’s create a reusable library of Shape types:
Shape.java
package org.fool.polymorphism; public class Shape { public void draw() { } public void erase() { } }
Circle.java
package org.fool.polymorphism; public class Circle extends Shape { @Override public void draw() { System.out.println("Circle.draw()"); } @Override public void erase() { System.out.println("Circle.erase()"); } }
Square.java
package org.fool.polymorphism; public class Square extends Shape { @Override public void draw() { System.out.println("Square.draw()"); } @Override public void erase() { System.out.println("Square.erase()"); } }
Triangle.java
package org.fool.polymorphism; public class Triangle extends Shape { @Override public void draw() { System.out.println("Triangle.draw()"); } @Override public void erase() { System.out.println("Triangle.erase()"); } }
PolymorphismTest.java
package org.fool.polymorphism; import java.util.Random; public class PolymorphismTest { public static class RandomShapeGenerator { private static Random rand = new Random(47); public static Shape next() { switch (rand.nextInt(3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } } public static void main(String[] args) { Shape[] shapes = new Shape[9]; // Fill up the array with shapes: for (int i = 0; i < shapes.length; i++) { shapes[i] = RandomShapeGenerator.next(); } // Make polymorphic method calls: for (Shape s : shapes) { s.draw(); } } }
The base class Shape establishes the common interface to anything inherited from Shape—that is, all shapes can be drawn and erased. The derived classes override these definitions to provide unique behavior for each specific type of shape.
RandomShapeGenerator is a kind of “factory” that produces a reference to a randomly-selected Shape object each time you call its next( ) method. Note that the upcasting happens in the return statements, each of which takes a reference to a Circle, Square, or Triangle and sends it out of next( ) as the return type, Shape. So whenever you call next( ), you never get a chance to see what specific type it is, since you always get back a plain Shape reference.
main( ) contains an array of Shape references filled through calls to RandomShapeGenerator.next( ). At this point you know you have Shapes, but you don’t know anything more specific than that (and neither does the compiler). However, when you step through this array and call draw( ) for each one, the correct type-specific behavior magically occurs, as you can see from the output when you run the program.
The point of creating the shapes randomly is to drive home the understanding that the compiler can have no special knowledge that allows it to make the correct calls at compile time. All the calls to draw( ) must be made through dynamic binding.
发表评论
-
Java 8 获取当前日期
2018-12-12 14:38 667原创转载请注明出处:https://agilestyle. ... -
abstract class 和 interface区别
2017-09-06 23:12 368原创转载请注明出处:http://agilestyle.i ... -
Difference between <? super T> and <? extends T>
2017-05-24 10:34 460原创转载请注明出处:http://agilestyle.i ... -
a=a+b和a+=b的区别
2017-03-02 22:47 622原创转载请注明出处:http://agilestyle.i ... -
Java Object 九大方法
2017-02-22 21:46 371原创转载请注明出处:http://agilestyle.i ... -
Java Collections Framework Diagram
2016-12-14 15:43 397原创转载请注明出处:http://agilestyle.i ... -
Java三大领域+Python的技能图谱
2016-08-25 09:48 1803转自:来吧 主流编程语言图谱+知识库都在这了 Ja ... -
Top 8 Diagrams for Understanding Java(转)
2016-08-23 10:24 274转自:http://www.programcreek.co ... -
stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
2016-05-27 14:56 3380原创转载请注明出处:http://agilestyle.i ... -
技术资料链接
2016-03-19 12:59 583LeeCode http://www.cnblogs.c ... -
Java取模
2015-09-13 11:41 717取模的规律:取模的结果符号永远与被除数的符号相同 pack ... -
Java面试——字符串
2013-09-18 22:53 925String中的常用方法 1.写出下面程序的输出结 ... -
Java面试——数组
2013-09-18 22:22 9141.下面哪几个选项是合 ... -
数据类型转换
2013-09-17 22:27 790数据类型的转换方式 ... -
Java面试——数据类型及类型转换
2013-09-16 22:42 13661.int和Integer有什么区别? 2.下面选 ... -
实例成员和类成员的区别
2013-09-16 12:05 1146下面关于实例成员的说法,哪些是正确的?CD A.实例成员也 ... -
clone() 方法
2013-03-11 13:54 775在应用开发过程中,我们可能会需要拷贝(copy)一个现有的 ... -
多线程实现方法
2013-03-06 11:05 712两种实现方法: 继承Thread类, 实现Runna ... -
Thread common example
2012-08-02 16:48 7761.设计 4 个线程,其中两个线程每次对 j增加1,另外两个线 ... -
Java Regular Expressions
2012-07-02 20:51 863使用正则表达式可以方便地对数据进行匹配,还可以 执行更加复杂的 ...
相关推荐
The design of a simplified banking program is introduced in chapter 1 in a non-object-oriented incarnation and the example is carried through all chapters. You can see the object orientation develop ...
Classes, Objects, Encapsulation, Inheritance, Polymorphism Integrated OOP Case Studies: Time, GradeBook, Employee Industrial-Strength, 95-Page OOD/UML® 2 ATM Case Study Standard Template Library (STL...
PRACTICAL, EXAMPLE-RICH COVERAGE OF: * Classes, Objects, Encapsulation, Inheritance, Polymorphism, Interfaces, Nested Classes * Integrated OOP Case Studies: Time, GradeBook, Employee * Industrial-...
Along the way you’ll enjoy the Deitels’ classic treatment of object-oriented programming and the OOD/UML® ATM case study, including a complete C# implementation. When you’re finished, you’ll be ...
Along the way you’ll enjoy the Deitels’ classic treatment of object-oriented programming and the OOD/UML® ATM case study, including a complete C# implementation. When you’re finished, you’ll be ...
In Java, the `String` class is a classic example of an immutable class. Once a `String` object is created, its value cannot be modified. Immutable objects are useful for ensuring thread safety and ...