初识Java之抽象类

一、抽象类基本介绍

1.抽象类的概念

在我们类和对象学习中,所有的对象都是依赖于类来实现,比如狮子是一种动物,海豚是一种动物。

class Animal{
    public String name;
    public Animal(String name) {
        this.name = name;
    }
    public void living(){
        System.out.println(name+"生活");
    }

}
class Lion extends Animal{
    public Lion(String name) {
        super(name);
    }

    @Override
    public void living() {
        System.out.println(name+"在陆地生活");
    }
}
class  Dolphin  extends  Animal{
    public Dolphin(String name) {
        super(name);
    }

    @Override
    public void living() {
        System.out.println(name+"在海洋生活");
    }
}
public class Main {
    public static void breath(Animal animal){
        animal.living();

    }
    public static void main(String[] args) {
//        Animal animal1=new Cat("猫咪");
//        Animal animal2=new Fish("海豚");
//
//        animal1.living();
//        animal2.living();

        breath(new Dolphin("海豚"));
        breath(new Lion("狮子"));

    }
}

我们分别利用方法传参的直接赋值两种向上转型的方法实现了多态,但是这个Aniaml在我们没有实现继承之前我们知道他到底是哪一种动物吗,没有。它无法形容任何一种动物是如何生存的。


看图⬇️
在这里插入图片描述

矩形、圆形、三角形都属于图形这个类,形成了继承关系。子类需要重写父类的方法,所以也继承了draw()这个方法。但是图形类他没有办法实现这个draw方法,因此我们可以将这个图形Shape类设计为抽象类。

抽象类的定义:如果一个类当中没有足够的信息来描述一个对象,就需要把这个类设计为抽象类

二、抽象类的特性

1.抽象类和普通类的区别

抽象类和普通的区别主要在于以下两点

1.抽象类不能被实例化
2.抽象类当中,可以包含非抽象方法和抽象方法,但是普通类只能包含非抽象方法

//1.被abstract修饰的类称为抽象类
//2.抽象方法可以不用方法体
//3.抽象类可以包含属性以及普通方法
abstract class Shape{ 

    abstract void draw();
    public  void func(){
        
        System.out.println("抽象类可以包含普通方法");
        
    }
    public double area;
    
}

区别1: 在给抽象类实例化的时候出现了错误,提示我们抽象类是无法实例化的。
在这里插入图片描述
区别2:
抽象类可以包含抽象和非抽象方法
在这里插入图片描述
普通类只能包含非抽象方法,如果想要包含抽象方法就必须将类修改成抽象类,并且将普通方法用关键字abstract修饰
在这里插入图片描述

2.对比抽象与非抽象方法

在我们的抽象类当中是无法具体形容一个对象的,在抽象类的中的方法也是没有方法体的,也就是说抽象方法可以没有具体的实现。但是前提是这个类必须要是抽象类,用abstract去修饰。

既然可以没有方法体,抽象方法中可以有构造方法吗?
在这里插入图片描述
因为在抽象类当中是可以存在属性的,进而肯定是可以存在构造方法的。构造方法存在的意义就是为了帮助属性进行初始化。其执行的顺序也是先执行父类的构造方法再执行子类的构造方法(这里涵盖抽象类的继承我们下一个小节会说明)

/**
 * @author Jason
 * @date 2023/1/14 21:15
 */

abstract  class Aniaml{
    public String name;

    public Aniaml(String name) {
        this.name = name;
        System.out.println("这是父类的构造方法");
    }

    public abstract void func();//存在于抽象类的抽象方法可以没有方法体,前提是必须是抽象类以及方法使用abstrac修饰
}

class Dog extends Aniaml{
    public Dog() {
        super("junjun");//父类中是有参数的,所以这里我们需要给到name的值
        System.out.println("这是子类的构造方法");//
    }

    @Override
    public void func() {//这里应该可以理解,因为子类继承了父类,所以必须重写父类的方法

    }
}
public class Test2 {
    public static void main(String[] args) {
        Aniaml aniaml=new Dog();//通过直接赋值的方式实现向上转型
    }
}

运行结果:
在这里插入图片描述
同样在抽象类当中也是可以包含静态staic修饰的方法

abstract  class A{
    public static void func(){
        System.out.println("func()是存在与抽象类中的静态方法");
    }
}
public class Test3 {
    public static void main(String[] args) {
        A.func();
    }
}

运行结果:静态方法可以直接通过类名调用
在这里插入图片描述

3.抽象类的继承

大致摸清楚抽象类的概念之后,我们似乎都有一个疑问,在介绍抽象类时,我们通过代码调试发现无法进行实例化,但是一个类存在必须要被实例化。那抽象类存在的意义到底是什么呢?
答案:被继承

当普通继承了抽象类

/**
 * @author Jason
 * @date 2023/1/14 22:07
 */
abstract  class Animal{
     public String name;
     abstract  public void breath();

    public Animal(String name) {
        this.name = name;
    }
}
class Shark extends Animal{
    public Shark(String name) {
        super(name);
    }

    @Override
    public void breath() {
        System.out.println(name+"使用鳃呼吸的");
    }
}
class Tiger extends  Animal{
    public Tiger(String name) {
        super(name);
    }

    @Override
    public void breath() {
        System.out.println(name+"使用嘴呼吸的");
    }
}
public class Test4 {
    public static void drawBreath(Animal animal){
        animal.breath();

    }
    public static void main(String[] args) {
//        Animal animal1=new Shark("鲨鱼🦈");
//        Animal animal2=new Tiger("老虎🐯");
//        drawBreath(animal1);
//        drawBreath(animal2);

         drawBreath(new Shark("🦈鲨鱼"));
         System.out.println("================");
         drawBreath(new Tiger("🐯老虎"));

    }
}

运行结果:
在这里插入图片描述
有趣的事情要来了,我是一个普通类,抽象类有抽象方法,我就不去重写你的抽象方法,你咬我啊?
在这里插入图片描述
报错出来一瞬间你就明白一个道理,当一个普通类去继承抽象类时,必须要重写父类的抽象方法

当然翻译界面也提到了,解决这个问题还有另外一种方法,就是将子类改成用abstract修饰,就暂时不会有报错出现。⬇️
在这里插入图片描述
虽然没有出现报错,但是在这里告诫各位,躲的了初一躲不了15,现在不重写抽象类的抽象方法,下次再出现这样的问题,你就必须要重写,编译器只能帮助你解决一部分的问题,在设计思想中,投机取巧的方式是不可取的 。

4.抽象方法修饰注意点

在我们多态的章节中提到过关于中提到过重写的注意点
在这里插入图片描述
大家联想一下,抽象类存在的意义是不是被继承,继承里面又存在重写方法,那么这样一来就理解的通顺了。关于重写的方法在这片文章可以查阅,链接: 重写补充

  • 用private去修饰抽象类方法
    当用private去修饰抽象方法时,代表这个方法只能在当前对象中使用,无法再被继承,我们抽象类存在意义时冲突的
    在这里插入图片描述
  • 用static修饰抽象方法
    还记得static的语法吗,static不依赖于对象,可以通过类来调用。 当抽象方法被static修饰,肯定也是报错状态

在这里插入图片描述

  • 用final去修饰抽象方法
    我们在继承章节也说道过,final关键字可以用来修饰变量,方法,以及类,一旦被final修饰就变成了常量,常量是无法再去更改的。
    在这里插入图片描述

补充抽象类不能被实例化

虽然我们不能对抽象类进行实例化。
在这里插入图片描述
但是我们可以对其子类进行实例化,利用直接赋值,达到向上转型的效果即可。
在这里插入图片描述

总结

抽象类特性总结

  • 抽象类通过abstract来修饰,内部可以包含成员属性,构造方法,普通方法。
  • 抽象类无法被实例化,但是可以通过对子类进行向上转型。
  • 抽象类当中可以包含抽象和非抽象方法。
  • 什么是抽象方法,一个方法被abstract修饰,没有具体的实现(没有方法体),一旦包含抽象方法,这个类必须是抽象类,或者类名用abstrcact修饰
  • 当一个普通类继承了抽象类,这个类必须重写抽象类中的抽象方法
  • 抽象类存在的意义就是被继承
  • 抽象方法是不能被priavte、final、static修饰的,和重写方法的规则相同
  • 抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类。
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值