多态是指一个对象可以拥有多种不同的形态,继承是实现多态的基础。
引用多态:父类引用可以指向本类的对象,也可以指向子类的对象
方法多态:
1、创建本类对象时,调用的方法为本类方法;
2、创建子类对象时,调用的方法为子类重写或继承的方法。
首先建立父类Animal,包含一个eat()方法,如下代码所示:
public class Animal { public void eat(){ System.out.println("动物可以吃东西"); } }
然后建立子类Dog继承父类Animal,并重写eat()方法。
public class Dog extends Animal{ public void eat(){ System.out.println("狗狗可以吃东西"); } }
最后建立一个Cat类继承Animal,并独有getMouse()方法。
public class Cat extends Animal{ public void getMouse(){ System.out.println("猫会抓老鼠"); } }
通过测试类进行测试发现,父类的引用不能调用子类独有的方法。
public class InitTest { public static void main(String[] args) { Animal obj1 = new Animal();//父类的引用指向本类对象 Animal obj2 = new Dog();//父类的引用指向子类对象 Animal obj3 = new Cat(); obj1.eat();//动物可以吃东西 obj2.eat();//20岁的狗狗可以吃东西 obj3.eat();//动物可以吃东西 } }
1.2 引用类型转换
向上类型转换(隐式或自动类型转换):子类转换为父类对象
向下类型转换(强制类型转换):父类转换为子类,有风险
向上类型转换好比是把杯子中的水倒进壶里,不会存在风险;而向下类型转换则是把壶里的水倒进杯子里,可能会溢出。为了避免这种风险的发生,可以使用instanceof关键字进行判断。如下代码所示:
public class InitTest { public static void main(String[] args) { Animal obj = new Dog();//向上类型转换 if(obj instanceof Dog){ Dog dog = (Dog)obj; //向下类型转换 }else{ System.out.println("不能进行Dog类型转换"); } if(obj instanceof Cat){ Cat cat = (Cat)obj; }else{ System.out.println("不能进行Cat类型转换"); } } }
程序能够正常运行,且不能进行Cat类型转换。
当某个父类只知道子类应该包含这些方法却不知如何实现时,需要用到抽象类。抽象类用abstract关键字修饰,它限制子类必须有哪些方法,但不关注实现。抽象类中可以包含普通方法,也可以没有方法。
例:利用抽象类编写程序,求矩形和圆的周长和面积。
实现步骤:
1、抽象出矩形和圆形的抽象类Shape作为父类,并定义要实现的方法求周长premeter()和求面积area();
2、分别创建子类Rectangle和Circle,继承抽象父类Shape;
3、根据相关图形的求解算法,分别实现父类的抽象方法。
public abstract class Shape { public abstract double perimeter(); public abstract double area(); } public class Rectangle extends Shape { double length; double width; public Rectangle(double length,double width){ this.length = length; this.width = width; } @Override public double perimeter() { return 2*(length+width); } @Override public double area() { return length*width; } } public class Circle extends Shape { double radius; final double PI = 3.14; public Circle(double radius){ this.radius = radius; } @Override public double perimeter() { return 2*PI*radius; } @Override public double area() { return PI*radius*radius; } } 这里,由于不同的形状求解周长和面积时,需要的参数个数不同,在定义抽象方法中无法统一给出参数,可以在子类中定义变量,通过初始化构造方法进行参数的传递。下面是测试方法代码: public class ShapeTest { public static void main(String[] args) { Shape s1 = new Rectangle(2,4); Shape s2 = new Circle(3.9); System.out.println("矩形的周长:"+s1.perimeter()); System.out.println("矩形的面积:"+s1.area()); System.out.println("圆形的周长:"+s2.perimeter()); System.out.println("圆形的面积:"+s2.area()); } }
接口是一种特殊的类,由全局变量和公共方法组成。它定义了某一批类的规范,而不关心这些类的内部数据和实现细节,只规定这些类里必须提供某些方法。
接口里的属性是常量,默认会加上public static final三个关键字,接口里的方法只能是抽象方法,默认会加上public abstract关键字。
一个类可以实现多个接口,但类必须是先继承,然后实现接口。
例:傻瓜机和智能机继承了父类手机,父类的抽象方法里面都定义了打电话和发短信的功能,而智能机和PSP都有玩游戏的功能。此时PSP不具备手机的特征所以不宜继承手机类,而可以将玩游戏定义为一个接口,由智能机和PSP实现。
public interface IPlayGame { public void playGame(); } public class SmartPhone extends Telphone implements IPlayGame{ @Override public void call() { System.out.println("SmartPhone可以打电话"); } @Override public void message() { System.out.println("SmartPhone可以发短信"); } @Override public void playGame() { System.out.println("玩游戏的功能"); } } public class PSP implements IPlayGame{ @Override public void playGame() { System.out.println("玩游戏的功能"); } } public class InterfaceTest { public static void main(String[] args) { IPlayGame ip1 = new SmartPhone(); IPlayGame ip2 = new PSP(); ip1.playGame(); ip2.playGame(); } }
接口还可以通过匿名内部类的方式实现,即没有名字的内部类。此方式常用于高级开发中。
public static void main(String[] args) { IPlayGame ip3 = new IPlayGame(){ @Override public void playGame() { System.out.println("使用匿名内部类的方式实现接口"); } }; ip3.playGame(); }
注:文章根据本站相关课程的学习笔记整理而来,有错误或其他任何问题敬请指正,欢迎共同学习交流!
以上就是Java面向对象基础:多态性,抽象类和接口的详细内容,更多关于Java面向对象多态性 抽象类和接口的资料请关注小牛知识库其它相关文章!
本文向大家介绍Python面向对象之接口、抽象类与多态详解,包括了Python面向对象之接口、抽象类与多态详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python面向对象之接口、抽象类与多态。分享给大家供大家参考,具体如下: 接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中
面向对象三要素:封装、继承、多态 封装:封装的意义,在于明确标识出允许外部使用的所有成员函数和数据项,或者叫接口。 继承: 继承基类的方法,并做出自己的扩展; 声明某个子类兼容于某基类(或者说,接口上完全兼容于基类),外部调用者可无需关注其差别(内部机制会自动把请求派发dispatch到合适的逻辑)。 多态:基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同。很显然,多态实际上是依附
本文向大家介绍Python面向对象基础入门之设置对象属性,包括了Python面向对象基础入门之设置对象属性的使用技巧和注意事项,需要的朋友参考一下 前言 前面我们已经介绍了 python面向对象入门教程之从代码复用开始(一) ,这篇文章主要介绍的是关于Python面向对象之设置对象属性的相关内容,下面话不多说了,来一起看看详细的介绍吧 用类存储数据 类实际上就是一个数据结构,对于python而言,
本文向大家介绍Java基础教程之接口的继承与抽象类,包括了Java基础教程之接口的继承与抽象类的使用技巧和注意事项,需要的朋友参考一下 在实施接口中,我们利用interface语法,将interface从类定义中独立出来,构成一个主体。interface为类提供了接口规范。 在继承中,我们为了提高程序的可复用性,引入的继承机制。当时的继承是基于类的。interface接口同样可以继承,以拓展原in
1. 抽象类 当定义一个类时,常常需要定义一些方法来描述该类的行为特征,但有时这些方法的实现方式是无法确定的。例如前面在定义Animal类时,shout()方法用于表示动物的叫声,但是针对不同的动物,叫声也是不同的,因此在shout()方法中无法准确描述动物的叫声。 针对上面描述的情况,Java允许在定义方法时不写方法体,不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰。
本文向大家介绍Java基础教程之Hello World到面向对象,包括了Java基础教程之Hello World到面向对象的使用技巧和注意事项,需要的朋友参考一下 Java是完全面向对象的语言。Java通过虚拟机的运行机制,实现“跨平台”的理念。我在这里想要呈现一个适合初学者的教程,希望对大家有用。 "Hello World!" 先来看一个HelloWorld.java程序。这个程序在屏幕上打印出
在实施接口中,我们利用interface语法,将interface从类定义中独立出来,构成一个主体。interface为类提供了接口规范。 在继承中,我们为了提高程序的可复用性,引入的继承机制。当时的继承是基于类的。interface接口同样可以继承,以拓展原interface。 接口继承 接口继承(inheritance)与类继承很类似,就是以被继承的interface为基础,增添新增的接口方法
问题内容: 在面试中,有人问我以下问题。我试图回答这个问题,但是我想确切回答这个问题。 如果我可以将Abstract类模拟为Interface,为什么Java提供了Interface? 这意味着如果在Abstract类中我可以将所有方法标记为abstract,然后abstract类将用作接口,那么为什么我需要接口。 谁能简单地解释一下我。 问题答案: 这是一个非常标准的面试问题。答案是:因为您可以