luogg_java学习_07_抽象类_接口_多态学习总结

这篇博客总结了半天,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用.
转载请注明 出自 : luogg的博客园 ,

抽象

一种专门用来做父类,被继承的. (模板)

格式:
abstract class 抽象类名{
    属性;
    普通方法;
    访问权限 abstract 返回值类型 方法名称([形参]);//抽象方法,无方法体
}

这里写图片描述

抽象类中, 不写访问权限的时候, 默认是default, 不同于接口中的默认(接口方法默认被public abstract 修饰), 子类在继承抽象类时候, 需要重写抽象类中方法, 修饰符可以默认不写(default)或者写public , 但在接口中重写时必须为public

抽象类的定义及使用:

1, 定义父类为抽象类,并定义没有方法体的抽象方法
2, 子类继承抽象类, 并重写父类的抽象方法,写入方法体,去掉abstract

使用抽象类注意事项:

1, 抽象类本身不可以创建对象, 因为它不可以被实例化,即不能构造一个该类的对象.
2, 抽象类有构造方法, 在子类实例化前也会默认的调用它的无参构造方法, 只要是类, 都有构造方法
3, 抽象类中不一定要有抽象方法,但是有抽象方法的类, 一定要被声明为抽象类,不然编译不通过
4, abstract只能修饰类和方法
abstract 不能用来修饰属性, 构造器, 不能与private , final , static 共用

  • 属性不能被覆盖,重写,
  • 构造器不能被重写
  • private只能在本类中调用,不能被继承,不能被重写
  • fianl修饰方法,不能被重写 , 修饰类, 不能被继承

抽象类与普通类的区别

这里写图片描述

接口

概念

接口可以理解为一种特殊的抽象类, 对行为的抽象, 由全局常量和公有抽象方法组成 , 接口的作用是用来被实现的(implement) , 接口属于复合类型,

定义

[访问修饰符] interface I接口名{
    属性(全局常量,默认被static final修饰);
    抽象的方法(没有方法体,方法默认被public abstract修饰);
}

这里写图片描述

注意事项:

1, 子类实现接口,重写方法的时候,修饰符必须加public,当接口中用默认的时候,因为接口方法默认是public+abstract修饰的
2, 接口没有构造方法,没有办法创建对象
3, 接口名字必须以大写I开头
4, 接口的作用是为了弥补java中的单继承,接口之间可以多extends,
5, 接口不可以继承抽象类, 但是接口可以extends 多个接口, 抽象类可以implements接口,普通类可以implements多个接口

接口和抽象的混搭使用

当子类既要继承抽象类 , 又要实现接口的时候, 先extends 抽象类, 然后再 implements 接口1,接口2..{}

public class Test2 {
    public static void main(String[] args) {
        P p1 = new P();
        p1.tell2();
//      static修饰的age,静态全局常量,
        System.out.println(I1.age);
        System.out.println(I2.age);
        System.out.println(I3.age);
        
        p1.tell1("花花");
        p1.tell1();
    }
}
//定义一个抽象类
abstract class Abs1 implements I1,I2{//抽象类可以implements多个接口,但是不可以extends接口
    String name;
//  抽象类可以有构造方法
    Abs1() {
        
    }
    Abs1(String name){
        
    }
    abstract void tell1();
}
//定义接口
interface I1 extends I2,I3{//接口和接口之间可以多extends,但是接口不可以extends抽象类,接口不可以implements接口
    int age = 10;//不可以使用int age;因为默认是final
    
    /*I1(){
        //Interfaces cannot have constructors
    }*/
    
//  定义接口的抽象类
    void tell2();
}

interface I2{
    int age = 20;
    void tell3();
}

interface I3{
    int age = 30;
    void tell4();
}
class P extends Abs1 implements I1,I2,I3{
//  抽象类可以有构造方法
    void tell1(String name) {
        System.out.println("抽象方法被执行...");
    }
    public void tell2() {
        System.out.println("接口1的方法被执行...");
    }
    public void tell3() {
        System.out.println("接口2的方法被执行...");
    }
    public void tell4() {
        System.out.println("接口3的方法被执行...");
    }
    @Override
    void tell1() {
        System.out.println("抽象方法被执行...");
    }

这里写图片描述

抽象类和接口的区别

这里写图片描述

多态

概念

一个事物的多种表现形态,多种状态.
1, 方法的重写与重载
2, 子类对象的多态性 Person p1 = new Man();
3, 父类的引用指向子类对象

多态的实现

向上转型

  • 向上转型,可以调用父类方法也可以调用本类方法
  • 但是父类和子类有相同方法sleep的时候,调用时候会调用子类方法
    向下转型(使用的不多)

instanceof关键字

表示运算符前面的这个对象是不是运算符后面的类的实例
对象 instanceof 类
只要是本类和本类的父类,都是返回true, 包括Object类

虚方法的调用

1, 当子类覆写了父类中的方法,在发生多态的时候,调用的是子类的方法
2, 通过父类的引用指向子类的对象实体, 当调用方法时, 实际执行的是子类重写父类的方法

使用多态

public class TeachTest {
    public static void main(String[] args) {
        //实例化一个新的数学老师,
        //向上转型,可以调用父类方法也可以调用本类方法
        //但是父类和子类有相同方法sleep的时候,调用时候会调用子类方法
        Teacher t1 = new MathTeacher();//向上转型
        t1.teach();
        t1.sleep();
        t1.speak();
        
        //强制将Teacher 转换为MathTeacher(向下转型)
        MathTeacher mt = (MathTeacher)t1;
        mt.teach();
        //使用封装了的方法
        EnglishTeacher e = new EnglishTeacher();
        TeacherAll(e);
        
        System.out.println(e instanceof Teacher);
    }
    /*
             如果要调用类的方法,先实例化一个类,然后分别调用
             MathTeacher mt = new MathTeacher();
             mt.teach();
             mt.sleep();
             ChineseTeacher ct = new ChineseTeacher();
             ct.teach();
             ct.sleep();
             发现这样比较麻烦,向上抽取,定义一个新的工具类TeachTest的TeacherAll方法,将方法封装进去
             */
    public static void TeacherAll(Teacher t) {
        t.sleep();
        t.teach();
    }
}

abstract class Teacher{
    abstract void teach();
    void sleep() {
        System.out.println("老师在睡觉...");
    }
    void speak() {
        System.out.println("老师正在说话...");
    }
}
class MathTeacher extends Teacher{
    void teach() {
        System.out.println("数学老师在讲数学...");
    }
    void sleep() {
        System.out.println("数学老师正在躺着睡觉...");
    }
}
class EnglishTeacher extends Teacher{
    void teach() {
        System.out.println("英语老师在教英语...");
    }
    void sleep() {
        System.out.println("英语老师睡在沙发上...");
    }
}

运行结果:
这里写图片描述

转载于:https://www.cnblogs.com/luogg/p/5789006.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值