Java 这是多态性吗?
我最近参加了一次采访,在采访中我意识到我的编程概念没有我想象的那么具体 有人问我,描述一下你以前工作中使用多态性的一段时间 经过一些思考,我说我们有一个记录类,每一个新的记录扩展。所以,如果我们有一个AddRecord或RemoveRecord或任何其他类型的记录,它们会扩展这个记录。记录界面如下所示:Java 这是多态性吗?,java,polymorphism,Java,Polymorphism,我最近参加了一次采访,在采访中我意识到我的编程概念没有我想象的那么具体 有人问我,描述一下你以前工作中使用多态性的一段时间 经过一些思考,我说我们有一个记录类,每一个新的记录扩展。所以,如果我们有一个AddRecord或RemoveRecord或任何其他类型的记录,它们会扩展这个记录。记录界面如下所示: public abstract Record{ public writeLine(String line); public getColumn(int column); public
public abstract Record{
public writeLine(String line);
public getColumn(int column);
public setHeader(String header);
...
}
public AddRecord extends Record{
public writeLine(String line){
// do something
}
// etc...
}
public MakeRecord{
Record r;
public setRecord(Object s){
if(s instanceof Record){
r = s;
}
}
public void printNewRecord(){
while(thingsToWrite){
r.writeLine(something);
}
}
}
我只是人手不够,所以请不要挑剔
我告诉他们这是使用多态性,因为无论记录类型如何,都可以在不知道记录类型的情况下编写。这是很有价值的,因为我们正在编写需要正确填充的文件,可以是零填充,也可以是空格填充等等
如果这不是多态性,请告诉我如何将我的示例更改为使用多态性的示例 长答案短:是的
根据韦伯斯特的观点,多态性是:a(1):一个物种以多种形式存在,不受性别差异的影响(2):一个基因以多种等位基因形式存在(3):一个物种中以多种形式存在一个分子(如酶);b:以两种或两种以上形式结晶的性质,具有不同的结构
我们关注的是定义a。这用java术语描述为使用1个“top”类来引用两个“bottom”类。就我所知,上面的例子显示了这一点。这个例子不适合解释多态性 Addrecord不是Record类的良好扩展。Addrecord应该是方法而不是类 所以基本上,您应该让Record类具有Addrecord方法,并且该方法可以被特殊记录(如-ColumnnameRecord)覆盖 如果您有从记录类派生的specialRecord类,并且记录类有被派生类重写的方法,那么您就有了多态性的好例子
当前示例在技术上正确,但在概念上不正确。多态性的一个非常基本的示例:
import java.util.ArrayList;
public class TestClass{
public static void main(String args[]) {
ArrayList animals = new ArrayList();
animals.add(new Bear());
animals.add(new Fish());
animals.add(new Animal());
for (Animal a : animals){
a.someMethod();
}
}
}
class Animal {
public void someMethod(){
System.out.println("I am an Animal");
}
}
class Bear extends Animal{
public void someMethod(){
System.out.println("I am a Bear");
}
}
class Fish extends Animal{
public void someMethod(){
System.out.println("I am a Fish");
}
}
abstract class PolyGeometricEntity
{
public int center_x__mm; // commen superset
public int center_y__mm; // commen superset
public void move(int d_x__mm, int d_y_mm) // commen superset
{
center_x__mm += d_x__mm;
center_y__mm += d_y_mm:
}
public abstract int area(); // commen superset on abstract level, but specialized at implementation level
public abstract void draw(); // commen superset on abstract level, but specialized at implementation level
}
class CircleEntity : PolyGeometricEntity
{
public override int area()
{
// circle specific
return 1;
}
public override void draw()
{
// draw a circle
}
}
class TriangleEntity : PolyGeometricEntity
{
public override int area()
{
// triangle specific
return 1;
}
public override void draw()
{
// draw a triangle
}
}
class PolyCanvas
{
List<PolyGeometricEntity> entities = new List<PolyGeometricEntity>();
void CreateEntity(string toCreateClass)
{
// assume that code is called by the ui
// you do not know what the user decides at runtime
// Polymorphism 'starting' now:
PolyGeometricEntity toCreate = null;
if (toCreateClass == "c") { toCreate = new CircleEntity(); }
else if (toCreateClass == "t") { toCreate = new TriangleEntity(); }
entities.Add(toCreate);
}
void ReDraw()
{
foreach (PolyGeometricEntity toDraw in entities)
{
toDraw.draw(); // polymorphism in action!
}
}
}
其输出为:
I am a Bear
I am a Fish
I am an Animal
因此,我们可以看到,在每种类型的对象上调用方法的循环都在Animal上调用它们,而在每个对象上调用的实际方法是对象拥有该方法的实现
显然,要使此方法起作用,集合中的每个对象都必须有此方法的实现,尽管它显然可以使用超类的版本(如果适用于该对象的话)
这意味着集合中的对象(作为如何使用它的示例)可以在运行时确定,并且不必单独类型转换回其真实形式,只需由父类类型或接口类型调用即可。这使得代码具有更大的灵活性,并且更易于维护。它还允许编写更通用、松散耦合的代码
简而言之就是这样。网上有很多例子可以看。这是一个绝妙的概念,值得花些时间去理解。多态性的另一个例子:
import java.util.ArrayList;
public class TestClass{
public static void main(String args[]) {
ArrayList animals = new ArrayList();
animals.add(new Bear());
animals.add(new Fish());
animals.add(new Animal());
for (Animal a : animals){
a.someMethod();
}
}
}
class Animal {
public void someMethod(){
System.out.println("I am an Animal");
}
}
class Bear extends Animal{
public void someMethod(){
System.out.println("I am a Bear");
}
}
class Fish extends Animal{
public void someMethod(){
System.out.println("I am a Fish");
}
}
abstract class PolyGeometricEntity
{
public int center_x__mm; // commen superset
public int center_y__mm; // commen superset
public void move(int d_x__mm, int d_y_mm) // commen superset
{
center_x__mm += d_x__mm;
center_y__mm += d_y_mm:
}
public abstract int area(); // commen superset on abstract level, but specialized at implementation level
public abstract void draw(); // commen superset on abstract level, but specialized at implementation level
}
class CircleEntity : PolyGeometricEntity
{
public override int area()
{
// circle specific
return 1;
}
public override void draw()
{
// draw a circle
}
}
class TriangleEntity : PolyGeometricEntity
{
public override int area()
{
// triangle specific
return 1;
}
public override void draw()
{
// draw a triangle
}
}
class PolyCanvas
{
List<PolyGeometricEntity> entities = new List<PolyGeometricEntity>();
void CreateEntity(string toCreateClass)
{
// assume that code is called by the ui
// you do not know what the user decides at runtime
// Polymorphism 'starting' now:
PolyGeometricEntity toCreate = null;
if (toCreateClass == "c") { toCreate = new CircleEntity(); }
else if (toCreateClass == "t") { toCreate = new TriangleEntity(); }
entities.Add(toCreate);
}
void ReDraw()
{
foreach (PolyGeometricEntity toDraw in entities)
{
toDraw.draw(); // polymorphism in action!
}
}
}
抽象类polygeometricientity
{
public int center\u x\u mm;//公共超集
public int center\u y\u mm;//公共超集
公共无效移动(int d_x___mm,int d_y_mm)//公共超集
{
中心×毫米+=d×毫米;
中心直径+=d直径:
}
public abstract int area();//在抽象级别上是common超集,但在实现级别上是专用的
public abstract void draw();//在抽象级别上是commo超集,但在实现级别上是专用的
}
类循环实体:多几何实体
{
公共覆盖int区域()
{
//圈特定
返回1;
}
公共覆盖无效绘图()
{
//画圈
}
}
类三角形实体:多边形几何实体
{
公共覆盖int区域()
{
//三角形特定
返回1;
}
公共覆盖无效绘图()
{
//画一个三角形
}
}
保利坎瓦级
{
列表实体=新列表();
void CreateEntity(字符串toCreateClass)
{
//假设代码由ui调用
//您不知道用户在运行时决定了什么
//多态性“正在启动”:
PolyGeometriceEntity toCreate=null;
如果(toCreateClass==“c”){toCreate=new CircleEntity();}
else if(toCreateClass==“t”){toCreate=new TriangleEntity();}
实体。添加(创建);
}
作废重画()
{
foreach(实体中绘制的多边形几何实体)
{
toDraw.draw();//多态性正在运行!
}
}
}
面试官有没有告诉你那不是多态性?(如果答案是“是”,继续下一次面试,不要回头看。)在我看来不错,也许你的想法实际上比你想象的要好。有时候面试官会玩一些愚蠢的心理游戏来测试你的信念水平。提前回顾这些东西不会有什么坏处。(好吧,除了instanceof
check.。那是干什么的?)好的,谢谢大家。我认为他在装傻,但感觉他不相信我,但这是通过电话:)一个更好的选择是使用方法setRecord(Record s)
,如果传递错误的内容,则会出现编译错误(这是您想要的)。按照现在的代码方式,您将不会遇到编译错误、运行时错误,并且您的代码可能不会执行您想要的操作。这里真的需要生物学定义吗?在OOP上下文中提供了多态性的良好定义。我没有询问,而是将其设置为社区wiki,这是有原因的。如果你认为这会有助于更好地用不同的方式表达,那么就去做吧。