Java中抽象类、接口、以及形式参数与返回值

这一块的内容主要是有关Java中的抽象类、接口,以及形式参数与返回值。

抽象类

概述:
用之前的猫狗、动物举例,动物中不应该具体的东西,而且动物中的吃方法、睡觉方法这些等都不应该也是具体,我们把一个不具体的功能称之为抽象的功能,也叫做抽象方法,而类中如果有抽象方法,该类必须定义为抽象类

抽象类的使用代码举例:

abstract class Animal{
//    public abstract void eat(){}  //这样写会报错,因为抽象方法不能有主体
    public abstract void eat();
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }
}

abstract class Dog extends Animal{};

public class AbstractDemo {
    public static void main(String[] args) {
//        Animal a = new Animal();  //Animal是抽象的,无法实例化
        Animal a = new Cat();
        a.eat();
    }
}
//猫吃鱼

特点:

  • 抽象类和抽象方法必须使用abstract关键字修饰
    格式:abstract class 类名 {}

  • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类

  • 抽象类不能实例化
    那么,抽象类如何实例化呢?
    按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态

  • 抽象类的子类

    • 要么是抽象类,不需要重写父抽象类的抽象方法
    • 要么重写抽象类中所有的抽象方法,那么这个时候子类是一个具体的类
  • 成员变量:可以是变量,也可以是常量

  • 构造方法:有。可以有构造方法,但是抽象类又不能具体实例化,有什么用呢
    用于子类访问父类的初始化

  • 成员方法:可以是抽象方法,也可以不是抽象方法

  • 如果抽象类中包含成员方法是抽象方法,那么就需要强制具体子类去重写

  • 如果抽象类中包含成员方法是非抽象方法,那么继承的子类可以不去调用,提高了代码的复用性

代码举例:抽象类中的成员方法是抽象方法,就需要强制子类重写;如果是非抽象方法,继承的子类可以不去调用

abstract class Animal2{
    public int num = 10;
    public final int num2 = 20;

    public Animal2(){}

    public Animal2(String name,int age){}

    public abstract void show();//抽象类中的抽象方法,就需要子类去强制重写

    public void show2(){//抽象类中的非抽象方法,继承的子类可以不去调用
        System.out.println("这是抽象类中一个具体的方法");
    }
}

class Dog2 extends Animal2{
    public void show(){
        System.out.println("这是Dog2类继承Animal2");
    }
}

public class AbstractDemo2 {
    public static void main(String[] args) {
           Animal2 a = new Dog2();
           a.num = 100;
           System.out.println(a.num);
//           a.num2 = 200;//无法改变final修饰的变量
        System.out.println("*****************************");
            a.show();
            a.show2();
    }
}
//100
//        *****************************
//        这是Dog2类继承Animal2
//        这是抽象类中一个具体的方法

猫狗案例练习:
具体事物:猫、狗
共性:姓名、年龄、吃饭
分析:从具体到抽象
猫:
成员变量:姓名、年龄
构造方法:无参构造、带参构造
成员方法:吃饭(猫吃鱼)
狗:
成员变量:姓名、年龄
构造方法:无参构造、带参构造
成员方法:吃饭(狗吃肉)
通过上面的分析,我们可以看到,这其中有一些共性的内容,所以我们提取出一个父类:Animal类,但由于吃饭的内容不同,所以就定义为抽象方法,由于吃饭是抽象方法,所以Animal类就必须要是抽象类
抽象动物类:
成员变量:姓名、年龄
构造方法:无参、有参
成员方法:抽象的吃饭方法 吃饭()

实现:从抽象到具体代码的实现
动物类:
成员变量:姓名、年龄
构造方法:无参、有参
成员方法:抽象的吃饭方法 吃饭()
狗类:
继承自动物类
无参、有参
重写方法
猫类:
继承自动物类
无参、有参
重写方法

abstract class Animal3{
    //姓名
    private String name;
    //年龄
    private int age;

    public Animal3(){}

    public Animal3(String name,int age){
        this.age = age;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //抽象的eat方法
    public abstract void eat();
}

class Cat3 extends Animal3{
    public Cat3(){}

    public Cat3(String name,int age){
        super(name,age);
    }

    public void eat(){
        System.out.println("猫吃鱼");
    }
}

class Dog3 extends Animal3{
    public Dog3(){}

    public Dog3(String name,int age){
        super(name, age);
    }

    public void eat(){
        System.out.println("狗吃肉");
    }
}

public class AbstractTest {
    public static void main(String[] args) {

        Dog3 dog3 = new Dog3();
        dog3.setAge(21);
        dog3.setName("张三");
        System.out.println(dog3.getName()+"------"+dog3.getAge());
        dog3.eat();

        Dog3 dog31 = new Dog3("李四", 22);
        System.out.println(dog31.getName()+"------"+dog31.getAge());
        dog31.eat();

        Animal3 a = new Dog3();
        a.setName("王五");
        a.setAge(23);
        System.out.println(dog31.getName()+"-------"+dog31.getAge());
        dog31.eat();

        Animal3 a1 = new Cat3("赵六",24);
        System.out.println(a1.getName()+"-------"+a1.getAge());
        a1.eat();
    }
}
//张三------21
//狗吃肉
//李四------22
//狗吃肉
//李四-------22
//狗吃肉
//赵六-------24
//猫吃鱼
  • 一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
    抽象类里面可以没有抽象方法
    不能创建对象

  • abstract不能和哪些关键字共存

    • private 冲突
    • final 冲突
    • static 冲突

代码举例 abstract 和private、final、static都冲突:

abstract class Fu{
//    public abstract void show();

    //Error:(7, 27) java: 非法的修饰符组合: abstract和private
//    private abstract void show1();

    //Error:(10, 25) java: 非法的修饰符组合: abstract和final
//    final abstract void show3();

    //Error:(14, 26) java: 非法的修饰符组合: abstract和static
//    static abstract void show4();

    public static void show5(){
        System.out.println("这是一个静态方法");
    }
}

class Zi extends Fu{
    public static void show5(){
        System.out.println("这是继承的一个静态方法");
    }
}

public class AbstractDemo3 {
    public static void main(String[] args) {
        Fu f = new Zi();
        f.show5();
        Fu.show5();
    }
}
//这是一个静态方法
//这是一个静态方法

接口

牢记接口是来做额外的动作的,来体现事物的扩展性

  • 接口的特点

    • 接口用关键字interface表示
      格式:interface 接口名 {}
    • 类实现接口用implements表示
      格式:class 类名 implements 接口名 {}
    • 接口不能实例化
      那么,接口如何实例化呢
      按照多态的方式,由具体的子类实例化,这也是多态的一种,接口多态
    • 接口的子类
      要么是抽象类
      要么重写接口中所有的抽象方法
  • 由此可见

    • 最常见的是接口多态
    • 抽象类多态
    • 具体的类多态

一个简单的接口举例:(可以理解为,使用接口,为cat猫类加了一个新的方法)

//定义一个动物训练接口
interface AnimalTrain{
    public abstract void jump();
}

class Cat1 implements AnimalTrain{
    public void jump(){
        System.out.println("猫跳高");
    }
}

public class InterfaceDemo {
    public static void main(String[] args) {
//        AnimalTrain animalTrain = new AnimalTrain();//抽象类无法实例化
        AnimalTrain a = new Cat1();//就可以直接理解为使用接口为cat猫添加了一个新的方法
        a.jump();
    }
}
//猫跳高
  • 接口成员的特点:
    成员变量:只能是常量,并且是静态的
    它里面默认有修饰符:public static final
    建议:全部手动给出
    构造方法:接口里面没有构造方法
    成员方法:只能是抽象方法,没有方法体
    默认修饰符是:public abstract
    建议:全部手动给出
  • 注意:虽然接口里面没有构造方法,但是,所有的类都默认继承一个类:Object,Object是类Object结构的根,每个class都有Object作为超类,所有对象(包括数组)都实现了这个类的方法

成员接口的成员变量默认修饰符:public static final
成员接口的成员方法默认修饰符:public abstract
代码举例:

interface Inter{
    int num1 = 20;
    public static final int num = 10;

    //接口里面没有构造方法
//    public Inter(){}

    //接口里面不能带有方法主体
//    public void show(){
//        System.out.println();
//    }

    public abstract void show();
}

class InterImpl implements Inter{
    //接口的子类,要么是抽象类,要么重写接口中所有的方法
    public void show(){

    }

    //进行初始化要有父类的构造方法,这里调用的是父类Object的无参构造方法
    public InterImpl(){
        super();
    }
}

public class InterfaceDemo2 {
    public static void main(String[] args) {
        Inter i = new InterImpl();
//        i.num1 = 30;//这里所有的成员变量给出的默认修饰符都是   public static final所以是不能修改的
        System.out.println(i.num);
    }
}
//10
  • 类与类
    继承关系,只能单继承,但是可以多层继承
  • 类与接口
    实现关系,可以单实现,可以多实现,还可以在继承一个类的同时实现多个接口
  • 接口与接口
    没有实现关系,只有继承关系,可以单继承,可以多继承

代码举例:

interface Father{
    public abstract void show();
}

interface Mother{
    public abstract void show2();
}

interface sister extends Mother,Father{}

class Son extends Object implements Father,Mother{
    public void show(){
        System.out.println("我是儿子");
    }

    public void show2(){
        System.out.println("我实现mother的接口");
    }
}

public class InterfaceDemo3 {
    public static void main(String[] args) {
        Father f = new Son();
        f.show();
        ((Son) f).show2();

    }
}
//我是儿子
//我实现mother的接口

小案例:猫狗案例加上跳高的额外功能
分析:从抽象到具体
猫:
姓名、年龄
吃饭、睡觉
狗:
姓名、年龄
吃饭、睡觉

由于存在共性功能,所以抽象提取一个父的抽象类:

动物:
姓名、年龄
吃饭()
睡觉(){}
猫:继承于动物
狗:继承于动物

由于跳高是一个额外的功能,不是动物特有的,不能放在动物抽象类中,所以定义一个接口

接口:
跳高

部分的猫:实现跳高
部分的狗:实现跳高

实现:从抽象到具体代码实现

代码:

interface Jump{
    public abstract void jump();
}

abstract class Animal4{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    Animal4(){}

    Animal4(String name,int age){
        this.age = age;
        this.name = name;
    }

    abstract void eat();

    public void sleep(){
        System.out.println("睡觉");
    }
}

class Cat4 extends Animal4{
    public Cat4(){}

    public Cat4(String name,int age){
        super(name, age);
    }

    public void eat(){
        System.out.println("猫吃鱼");
    }
}

class Dog4 extends Animal4 implements Jump{
    public Dog4(){}

    public Dog4(String name,int age) {
        super(name, age);
    }

    public void eat(){
        System.out.println("狗吃肉");
    }

    public void jump(){
        System.out.println("狗跳高");
    }
}

public class InterfaceTest1 {
    public static void main(String[] args) {
        Animal4 a  = new Dog4("张三",21);
        System.out.println(a.getName()+"---"+a.getAge());
        a.eat();
        ((Dog4) a).jump();
    }
}
//张三---21
//狗吃肉
//狗跳高

形式参数和返回值

形式参数

  • 形式参数:
    基本数据类型
    引用数据类型:
    类:实际上需要的是该类的对象
    抽象类
    接口

类:实际上需要的是该类的对象 代码举例:

class Student3{
    public void study(){
        System.out.println("好好学习");
    }
}

class Student3Demo{
    public void fun(Student3 s){
        s.study();
    }
}

public class StudentTest {
    public static void main(String[] args) {
        Student3 student3 = new Student3();
        Student3Demo student3Demo = new Student3Demo();
        student3Demo.fun(student3);
    }
}
//好好学习
  • 形式参数:
    基本数据类型
    引用数据类型:
    类:实际上需要的是该类的对象
    抽象类:当抽象类作为形式参数传入方法的时候,需要的是该抽象类的子类对象
    接口

抽象类:当抽象类作为形式参数传入方法的时候,需要的是该抽象类的子类对象 代码举例

abstract class Person3{
    public abstract void study();
}

class PersonDemo{
    public void fun(Person3 p){
        p.study();
    }
}

class Student4 extends Person3{
    public void study(){
        System.out.println("学生学习");
    }
}

public class PersonTest {
    public static void main(String[] args) {
//        Person3 person3 = new Person3();//抽象类不能实例化

        Student4 student4 = new Student4();
        Person3 p =new Student4();

        PersonDemo personDemo = new PersonDemo();
        personDemo.fun(student4);
        personDemo.fun(p);
    }
}
//学生学习
//学生学习
  • 形式参数:
    基本数据类型
    引用数据类型:
    类:实际上需要的是该类的对象
    抽象类:当抽象类作为形式参数传入方法的时候,需要的是该抽象类的子类对象
    接口:当接口作为形式参数传入方法的时候,需要的是该接口具体的实现类对象

接口:当接口作为形式参数传入方法的时候,需要的是该接口具体的实现类对象
代码举例:

interface Person6{
    public abstract void study();
}

class Person6Demo{
    public void fun(Person6 p){
        p.study();
    }
}

class Teacher6 implements Person6{
    public void study(){
        System.out.println("老师学习");
    }
}

public class TeacherTest {
    public static void main(String[] args) {
        Teacher6 teacher6 = new Teacher6();
        Person6Demo person6Demo = new Person6Demo();
        person6Demo.fun(teacher6);
    }
}
//老师学习

返回值

  • 返回值类型:
    基本数据类型
    引用数据类型
    类:当一个类作为返回值类型的时候,需要的是该类的对象
    抽象类
    接口

类:当一个类作为返回值类型的时候,需要的是该类的对象 代码举例:

class Student7{
    public void study(){
        System.out.println("好好学习");
    }
}

class Student7Demo{
    public Student7 getStudent7(){
//        return new Student7();
        Student7 student7 = new Student7();
        return student7;
    }
}

public class StudentTest2 {
    public static void main(String[] args) {
        Student7Demo student7demo = new Student7Demo();
        Student7 student7 = student7demo.getStudent7();
        student7.study();
    }
}
//好好学习
  • 返回值类型:
    基本数据类型
    引用数据类型
    类:当一个类作为返回值类型的时候,需要的是该类的对象
    抽象类:当抽象类作为返回值类型的时候,需要的是该抽象类的子类对象
    接口

接口类:当一个类作为返回值类型的时候,需要的是该类的对象

abstract class Person7{
    public abstract void study();
}

class Doctor7 extends Person7{
    public void study(){
        System.out.println("医生学习");
    }
}

class Person7Demo{
    public Person7 getPerson(){
        Person7 p = new Doctor7();
        return p;
    }
}

public class PersonTest2 {
    public static void main(String[] args) {
        Person7Demo person7Demo = new Person7Demo();
        Person7 p  = person7Demo.getPerson();
        p.study();
    }
}
//医生学习
  • 返回值类型:
    基本数据类型
    引用数据类型
    类:当一个类作为返回值类型的时候,需要的是该类的对象
    抽象类:当抽象类作为返回值类型的时候,需要的是该抽象类的子类对象
    接口:当接口作为返回值类型的时候,需要的是该接口实现类的对象

接口:当接口作为返回值类型的时候,需要的是该接口实现类的对象 代码举例:

interface PlayGame{
    public void playGame();
}

class PlayGameDemo{
    public PlayGame getPlayGame(){
        PlayGame p = new Teacher7();
        return p;
    }
}

class Teacher7 implements PlayGame{
    public void playGame(){
        System.out.println("玩游戏");
    }
}

public class TeacherTest2 {
    public static void main(String[] args) {
        PlayGameDemo playGameDemo = new PlayGameDemo();
        PlayGame p = playGameDemo.getPlayGame();
        p.playGame();
    }
}
//玩游戏

感谢阅读,我是啊帅和和,一位大数据专业即将大四学生,祝你快乐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊帅和和。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值