Java面向对象基础之多态性,抽象类和接口

 更新时间:2020年05月29日 16:25:16   作者:亚努人  
这篇文章主要介绍了Java面向对象基础:多态性,抽象类和接口,文中代码可以帮助各位更好的理解学习,有需求的小伙伴可以参考下

一、多态性

多态是指一个对象可以拥有多种不同的形态,继承是实现多态的基础。

1.1 引用多态和方法多态

引用多态:父类引用可以指向本类的对象,也可以指向子类的对象

方法多态:
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类型转换。

二、抽象类与接口

2.1 抽象类

当某个父类只知道子类应该包含这些方法却不知如何实现时,需要用到抽象类。抽象类用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());
 }
}

2.2 接口

接口是一种特殊的类,由全局变量和公共方法组成。它定义了某一批类的规范,而不关心这些类的内部数据和实现细节,只规定这些类里必须提供某些方法。

接口里的属性是常量,默认会加上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面向对象多态性 抽象类和接口的资料请关注脚本之家其它相关文章!

相关文章

  • java注解之运行时修改字段的注解值操作

    java注解之运行时修改字段的注解值操作

    这篇文章主要介绍了java注解之运行时修改字段的注解值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Java多线程4种拒绝策略小结

    Java多线程4种拒绝策略小结

    当线程池中的任务队列已满且无法再接受新的任务时,就需要采取拒绝策略来处理这种情况,本文主要介绍了Java多线程拒绝策略,包含了四种常见的拒绝策略,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • springmvc拦截器登录验证示例

    springmvc拦截器登录验证示例

    本篇文章主要介绍了springmvc拦截器登录验证示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 使用SpringMVC在redirect重定向的时候携带参数的问题

    使用SpringMVC在redirect重定向的时候携带参数的问题

    这篇文章主要介绍了使用SpringMVC在redirect重定向的时候携带参数的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Idea热加载插件JRebel激活以及使用教程

    Idea热加载插件JRebel激活以及使用教程

    JRebel是一款JVM插件,它使得Java代码修改后不用重启系统,立即生效,下面这篇文章主要给大家介绍了关于Idea热加载插件JRebel激活以及使用的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • IntelliJ IDEA 2020 安装和常用配置(推荐)

    IntelliJ IDEA 2020 安装和常用配置(推荐)

    这篇文章主要介绍了IntelliJ IDEA 2020 安装和常用配置(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • WebSocket无法注入属性的问题及解决方案

    WebSocket无法注入属性的问题及解决方案

    这篇文章主要介绍了WebSocket无法注入属性的问题及解决方法,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • 【spring-boot】快速构建spring-boot微框架的方法

    【spring-boot】快速构建spring-boot微框架的方法

    本篇文章主要介绍了【spring-boot】快速构建spring-boot微框架的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Mybatis分页查询的实现(Rowbounds和PageHelper)

    Mybatis分页查询的实现(Rowbounds和PageHelper)

    本文主要介绍了Mybatis分页查询的实现(Rowbounds和PageHelper),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 一文带你你搞懂Java的3种IO模型

    一文带你你搞懂Java的3种IO模型

    在Java中,一共有三种IO模型,分别是阻塞IO(BIO)、非阻塞IO(NIO)和异步IO(AIO),本文将给大家详解的介绍这三种IO模型,文中有相关的代码示例,需要的朋友可以参考下
    2023-05-05

最新评论