Java十分钟精通多态与抽象类的使用与原理

我们知道Java的三大特性:封装、继承、多态。前两个之前在Java入门(六)已经讲到,现在来讲多态这个特性。

什么是多态?

多态顾名思义即为多种形态的意思

Java中多态的含义:

  • 发送消息给某个对象,让这个对象自行决定采用哪种行为响应这个消息
  • 子类对象的引用赋值给父类引用变量来实现动态的方法调用

Java中形成多态的前提:

  • 继承
  • 父类方法的重写
  • 向上转型

我对多态的解释:

比如我们,是人,也是学生,也是年轻人,我可以用人的身份去做事情,也可以用学生的身份去买学生票,也可以用年轻人的身份做公益,这样我们可以通过不同的形态去做不同的事情。这样是不是更好理解一点?

注意:

多态前提条件:必须有子父类关系。

在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

多态的定义与使用格式:

父类类型 变量名=new 子类类型();

多态中成员的特点:

  • 多态成员变量:编译运行看左边
  • 多态成员方法:编译看左边,运行看右边

多态的转型:

  • 多态的转型分为向上转型和向下转型两种
  • 向上转型:多态本身就是向上转型过的过程
  • 使用格式:父类类型 变量名=new 子类类型();
  • 适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。
  • 向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型
  • 使用格式:子类类型 变量名=(子类类型) 父类类型的变量;
  • 适用场景:当要使用子类特有功能时。

代码解释:

public class Person {     //人类,作为父类使用
    public void speak(){
        System.out.println("我们都是一个人");
    }
}

public class Student extends Person{    //继承父类,相当于我们是学生,有人的方法
    @Override
    public void speak(){
        System.out.println("我是人类中的学生");
    }
}

public class Child extends Person{   //继承父类,相当于我们是孩子,有孩子的行为
    @Override
    public void speak(){

        System.out.println("我是人类中的孩子");
    }
}

//测试类
public class TestMain {
    public static void main(String[] args) {

		//父类类型 变量名=new 子类类型();
        Person p = new Student();   //子类对象的引用赋值给父类
        p.speak(); //多态 相当于这里使用的是Student的方法。输出我是人类中的学生
        //我作为人,我用学生的身份,说出:我是人类中的学生

		Person p = new Child();
		p.speak();  //输出:我是人类中的孩子
		//我作为人,用孩子的身份,说出我是人类中的孩子

    }
}

//这段代码,我们用到了 继承,重写,向上转型,因为多态本来就是向上转型的过程

多态的作用:

介绍完多态,讲讲多态有什么用呢?为什么多态可以作为Java的三大特性。肯定是有原因的:

  • 提高代码的可重用性
  • 降低模块之间的耦合度

这里给大家介绍一下什么是多态机制?Java语言是如何实现多态的?(可能有点难以理解,本人对于该内容也没用理解充分,但这也是面试会考的题)

所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并 不确定,而是在程序运行期间才确定,即一个引用变量倒 底会指向哪个类的实例对象,该引用变量发出 的方法调用到底是哪个类中实现的 方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具 体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而 导致该引用 调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时 所绑定的具体代码,让程序可以选 择多个运行状态,这就是多态性。 多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要 是指方法的 重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不 同的函数, 在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来 实现的,也就是我们所说的多态性。

对于多态的理解,还可以参考一段代码:

class People{     //父类
    public void eat(){
        System.out.println("我们会吃饭");
    }
}

class Student extends People{  //继承父类
    @Override
    public void eat(){
        System.out.println("我会吃肉");
    }
    public void study(){
        System.out.println("我们要好好学习");
    }
}

class Teacher extends People{     //继承父类
    @Override
    public void eat(){
        System.out.println("老师会吃蔬菜");
    }
    public void teach(){
        System.out.println("老师要认真上课");
    }
}

//测试类:
public class TestMain {
    public static void main(String[] args) {
        People p=new Stu();      //子类对象的引用赋值给父类
        p.eat();       //输出: 我会吃肉
    }
}

抽象类:

什么是抽象类?

普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。

抽象方法:

在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。也就是说,抽象类里面的抽象方法,可以不写,在被继承后,再重写。

抽象类声明关键字:abstracat

定义一个抽象类:

public abstract class studnet{//定义一个抽象类

	public void study(){                         //普通方法
		System.out.println("我会学习");
	}

	public abstract void eat();         //抽象方法,没有方法体,有abstract关键字做修饰

}

//注意: 有抽象方法,这个类必须是抽象的!!!

举例解释:

形状类Shape需要提供用于计算面积和周长的方法,但是形状本身没有被确定,那么计算周长和面积的方法就无法确定,此时我们就需要使用抽象类和抽象方法。

由于Shape类计算周长和面积的方法无法确定,那么就可以将这样的方法声明为抽象的,以便在具体的子类中进行实现。

//定义一个shape类,但是没有具体的形状,所以我们定义成抽象类
public abstract class Shape {

    private int a;
    public abstract void area(){}     //求面积的方法
    public abstract void perimeter();   //求周长的方法

    public Shape() {    //无参构造
    }

    public Shape(int a) {
        this.a = a;
    }
}
//计算圆形面积的子类

public  abstract class shape {    //有抽象方法的类,则一定是抽象类,需要关键字abstract修饰

        private int a;
        public abstract void area();     //求面积的方法,没有方法体的方法,需要关键字abstract修饰
        public abstract void perimeter();   //求周长的方法
}

//创建计算圆面积和周长的子类,并继承抽象类shape,并重写shape内的方法
public class Circle extends shape{

    public static double pi = 3.14;
    private double r;  //半径

    @Override
    public void area() {
        System.out.println("圆的面积:"+Circle.pi*this.r*this.r);
    }

    @Override
    public void perimeter() {
        System.out.println("圆的周长为:"+2*Circle.pi*this.r);
    }

    public Circle() {
    }

    public Circle(double r) {  //
        this.r = r;
    }

}

//测试类:
public class TestMain {
    public static void main(String[] args) {
        Circle c = new Circle(5);        //传入半径为:5
        c.area();
        c.perimeter();

    }

}

//输出结果: 圆的面积:78.5
// 圆的周长为:31.400000000000002

抽象方法和抽象类的注意事项:

  • 抽象类中是可以有构造函数的,并且构造函数的写法和其它类没有区别,只不过它真正跑起来是因为子类构造函数的super调用,毕竟我们没办法new一个抽象类对象出来,只能把抽象类的构造函数交给子类的构造函数去使用。
  • 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类。
  • 抽象类的子类,必须重写父类中所有的抽象方法,如果有一个抽象方法没有重写,都会出现编译错误不给过,这时也可以把子类也声明为抽象类,报错就会消失。

简洁总结:

  • 抽象方法:没有方法体的方法,需要关键字abstract修饰
  • 有抽象方法的类,则一定是抽象类,需要关键字abstract修饰
  • 抽象方法不能使用private和static修饰
  • 抽象类,不一定有抽象方法的类
  • 抽象类,不一定有抽象方法的类
  • 抽象类可以有构造函数

普通类和抽象类有哪些区别?

  • 普通类不能包含抽象方法,抽象类可以包含抽象方法
  • 抽象类不能直接实例化,普通类可以直接实例化。

到此这篇关于Java十分钟精通多态与抽象类的使用与原理的文章就介绍到这了,更多相关Java 多态 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

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

    一.多态性 多态是指一个对象可以拥有多种不同的形态,继承是实现多态的基础. 1.1 引用多态和方法多态 引用多态:父类引用可以指向本类的对象,也可以指向子类的对象 方法多态: 1.创建本类对象时,调用的方法为本类方法: 2.创建子类对象时,调用的方法为子类重写或继承的方法. 首先建立父类Animal,包含一个eat()方法,如下代码所示: public class Animal { public void eat(){ System.out.println("动物可以吃东西"); }

  • java 多态与抽象类详解总结

    目录 前言 多态 初识多态 什么是多态? 多态的分类 多态的必要条件 实现多态 向上转型 向下转型 instanceof运算符 具体实现 抽象类与抽象方法 为什么要使用抽象? 抽象方法 抽象类 前言 今天是2021LOL全球总决赛,一直不被大家看好的EDG冲到了决赛对战韩国队的DK,可以说EDG面对如此强大的对手,想赢是比较难的,为了给中国队打气我立下flag,如果EDG获胜那我就奖励自己学习到第二天6点,结果我就来了,,,恭喜EDG! 为了接下来接口的学习,我们先来学习多态与抽类相关的一些知识

  • Java抽象类、继承及多态和适配器的实现代码

    Java继承 方法重写是Java语言多态的特性,必须满足以下条件 在子类中,方法名称与父类方法名称完全相同 方法的参数个数和类型完全相同,返回类型完全相同 方法的访问修饰符访问级别不低于父类同名方法的访问级别 在方法上添加@override注释,如果报错说明不是重写 方法重写限制 final修饰的父类方法在子类中不能被重写 static修饰的父类方法在子类中不能被重写,只能覆盖 super关键字 super关键字和this类似,super修饰的是父类的对象,如super();调用的是父类的默认无

  • java 方法重写与权限修饰符以及多态和抽象类详解概念和用法

    1.方法重写 子类写和父类一样的方法定义 public void call(){ System.out.println("输出文字"); //父类的方法 } public void call(){ System.out.println("helloworld"); } //子类的方法 重写父类方法时,容易写错名字怎么办? 加个@Override 注解 如果报错,说明重写父类方法时,写错了 @Override: @Override public void call()

  • Java语法之 Java 的多态、抽象类和接口

    目录 一.多态 1. 向上转型 2. 动态绑定 3. 方法重写 4. 向下转型 5. 关键字 super 6. 在构造方法中调用重写方法(坑) 7. 理解多态 8. 小结 二.抽象类 1. 概念 2. 注意事项 3. 抽象类的意义 3. 抽象类的作用 三.接口 1. 语法规则 2. 实现多个接口 3. 接口的继承 4. Comparable 接口 4. Comparator 接口 5. Cloneable 接口和深拷贝 上一篇文章:Java 基础语法之解析 Java 的包和继承 今天这章主要介绍

  • Java多态性抽象类与接口细致详解

    目录 1.多态性 1.1 向上转型 1.2 向下转型 2.抽象类 2.1 抽象类的基本概念 3.接口 3.1 接口的基本概念 3.2 接口的使用限制 3.3 使用接口定义标准 3.4 抽象类与接口的区别 1.多态性 多态性是面向对象的最后一个特征,它本身主要分为两个方面: ​ 方法的多态性:重载与覆写 ​ 1 重载:同一个方法名称,根据参数类型以及个数完成不同功能: ​ 2 覆写:通一个方法,根据操作的子类不同,所完成的功能也不同. ​ 对象的多态性:父子类对象的转换. ​ 1 向上转型:子类对

  • Java十分钟精通多态与抽象类的使用与原理

    我们知道Java的三大特性:封装.继承.多态.前两个之前在Java入门(六)已经讲到,现在来讲多态这个特性. 什么是多态? 多态顾名思义即为多种形态的意思 Java中多态的含义: 发送消息给某个对象,让这个对象自行决定采用哪种行为响应这个消息 子类对象的引用赋值给父类引用变量来实现动态的方法调用 Java中形成多态的前提: 继承 父类方法的重写 向上转型 我对多态的解释: 比如我们,是人,也是学生,也是年轻人,我可以用人的身份去做事情,也可以用学生的身份去买学生票,也可以用年轻人的身份做公益,这

  • Java十分钟精通集合的使用与原理上篇

    目录 什么是集合? 集合分为Collection和Map两种体系 一.Collection接口: 二.Map接口下分为HashMap和TreeMap: 集合总结: Collections工具类: 什么是集合? 比如我们去买超市买很多东西,我们不可能拿一样就去收银台,我们可能是先放到购物车内,然后再统一处理,所以购物车相当于一个容器,可以装很多东西,在Java中的集合也是相当于一个容器,可以装很多数据. 集合继承关系图: 但是这张图太复杂了,我们看一张简便的: 集合分为Collection和Map

  • Java十分钟精通进阶工厂方法模式

    目录 一.什么是工厂方法模式? 二.工厂方法模式的优缺点 三.模式的结构与实现 四.工厂方法模式代码实现 五.总结 一.什么是工厂方法模式? 工厂方法模式:也叫虚拟构造器模式或者多态工厂模式,它属于类创建型模式. 在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类. 我们知道在现在的真实工厂内分工越来越细,越来越专业化..各种产品有专门的工厂生产,

  • Java十分钟精通接口的使用与原理

    何为接口? 官方解释: Java内的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 个人理解解释: 其实接口可以理解为一种特殊的类,这个类里面全部是由全局常量和**公共的抽象方法(需要重写)所组成.接口是解决Java无法使用多继承的一种手段.我们可以把接口理解为是一个100%的抽象类,既接口中的方法必须全部是抽象方法.反正接口里面都是方法,但是没有方法体,其他类实现这个接口后重

  • Java十分钟精通泛型的使用与原理

    什么是泛型? 简而言之:<>泛型就是用来约束类.方法.属性上的数据类型,比如 List<Integer> list = new ArrayList<Integer>(); new ArrayList这个集合的元素只能添加Integer类型. 为什么需要泛型? Java推出泛型之前,程序员可以构建一个Object类型的集合,该集合能够存储任何的数据类型,而在使用该 集合的时候,需要程序员明确知道每个元素的具体的类型并向下转型,否则容易引发ClassCastExceptio

  • Java十分钟精通进阶适配器模式

    目录 1.什么是适配器模式? 2.适配器模式的定义 3.适配器模式的优缺点 4.适配器模式的结构与实现 5.适配器模式的代码实现 6.适配器模式的应用场景 1.什么是适配器模式? 其实适配器这三个字大家应该很熟悉,我们知道苹果公司的手机iPhone已经不提供充电插头了,包装盒内只有一根数据线,那么我们无法单独使用这根数据线进行在220V的插板上充电,因此我们需要重新购买一个适配器来把插板和手机连接起来,这就是适配器. 其实在软件设计中也可能出现,需要开发的具有某种业务功能的组件在现有的组件库中已

  • Java十分钟精通反射机制原理

    什么是反射? 反射机制是在运行状态中,它为Java提供一种"操作对象"的能力,在运行状态下,通过Class文件对象,可以调用到任何类里面的属性.方法.以及构造方法,包括私有的,所有的类在反射机制面前都是透明的 自己的概括:通过Class文件对象可以看到这个类里面的所有东西,并且可以使用和修改 反射的前提是获取Class文件对象((字节码对象),那么一共有三种方式获取: Class.forName("全类名") ----通过Class类的静态方法(最常用) 类名.cl

  • Java十分钟精通集合的使用与原理下篇

    List集合: ArrayList: 底层是数组结构,储存有序并且可以重复的对象 package SetTest; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ArrayListTest { public static void main(String[] args) { //创建ArrayList的对象 List<Integer> list = ne

  • Java十分钟精通Log4j日志的使用

    目录 为什么要用日志? 下载: 详细步骤: 一.打开IDEA 二.创建日志对象 为什么要用日志? 我们知道,程序在运行过程中会产生很多很多信息,比如在几点几分的时候运行了,运行的结果是怎么样的?为了我们更加了解程序运行的情况,可以通过日志来查看,日志可以在控制台输出,也可以输出至指定的文件内,在下面的文章中具体的给大家介绍. 下载: Log4J是Apache公司的开源项目,用于日志处理.下载地址: https://logging.apache.org/log4j/2.x/download.htm

  • Java十分钟精通异常处理机制

    目录 异常处理机制的底层原理 异常的继承关系图 异常的处理 一.try-catch-finally结构 二.多catch处理不同的异常: 三.throws声明异常/throw抛出异常: 四.自定义异常: 五.常见的异常 异常处理机制的底层原理 抛出异常,在执行一个方法时,如果发送了异常,则这个方法生成代表该异常的一个对象,停止当前执行的 路径,并把异常提交给jre. 捕获异常:jre得到该异常后,虚招相应的代码来处理该异常.jre在方法的调用栈中查找,从生成异常的 方法开始回溯,直到找到相应的异

随机推荐