Java学习笔记——Java语言基础(九)(抽象类、接口、抽象类和接口作为方法参数及返回值类型)

一、抽象类与接口

1.1 抽象类的概述

1.概述:在Java中,一个没有方法体的方法应该定义为抽象方法,当类中有抽象方法的时候,该类必须定义为抽象类。
2.特点

   (1)抽象类和抽象方法必要用abstract关键字修饰
        抽象类格式: abstract  class 类名 { }
        抽象方法格式:public abstract 返回值 方法名()
   (2)抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
   (3)抽象类可以有构造方法,抽象类不能进行实例构造。抽象类中的构造方法便于子类访问父类数据时的初始化
   (4)抽象类的实例化:按照多态的形式,有具体的子类实例化。抽象类多态
   (5)抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法

3.抽象类的成员特点

   (1)成员变量:可以是变量,也可以是常量
   (2)成员方法:抽象方法和非抽象方法都可以
   (3)构造方法:抽象类中有构造方法,用于子类访问父类数据的初始化

4.抽象类的练习

public class Test01 {
    public static void main(String[] args) {
        //new一个子类的时候,会调用父类的构造方法
        BB bb = new BB();
        bb.show();
    }
}
abstract class AA{
    //抽象类作为父类的构造方法,用于子类访问父类的初始化
    public AA(){
        System.out.println("抽象方法的构造方法");
    }
    public abstract void show();
}
class BB extends AA{
    //重写父类的show方法
    @Override
    public void show() {
        System.out.println("继承抽象类重写的抽象方法");
    }
}

运行结果:

Java学习笔记——Java语言基础(九)(抽象类、接口、抽象类和接口作为方法参数及返回值类型)_第1张图片
5.抽象类中abstract关键字的冲突

一个类如果没有抽象方法,也可以定义为一个抽象类,这样的话这个类就不能够创建对象。
abstract关键字不能与private关键字共存:private为私有,不能被继承更谈不上重写
abstract关键字不能与final关键字共存:当final修饰成员方法是,被修饰的成员方法不能被重写
abstract关键字不能与static共存:static修饰的方法为静态方法,属于类所有。

1.2 接口

1.接口的概述:为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现。
2.接口的特点

   (1)接口用关键字interface表示  格式: interface 接口名 { }
   (2)类实现接口使用implements关键字   格式: class 类名 implements 接口名 { }
   (3)接口使用多态进行实例化
   (4)接口的子类
       a.可以是抽象类,但是意义不大
       b.可以是具体类,要重写接口中的所有抽象方法

3.接口的成员特点
(1)成员变量:只能是常量,并且是静态的。默认修饰符:public static final
(2)构造方法:接口中不存在构造方法
(3)成员方法:只能是抽象方法,默认修饰符:public abstract
4.接口练习:

public class Test01 {
    public static void main(String[] args) {
        //使用多态进行实例化
        MyInterface aa = new AA();
        //静态 常量通过类名调用
        int num = MyInterface.NUM;
        System.out.println(num);//20
        int a = MyInterface.a;
        System.out.println(a);//15
        int a1 = AA.a;
        System.out.println(a1);//15
        int num1 = AA.NUM;
        System.out.println(num1);//20
        aa.show();
        aa.test();
    }
}
interface MyInterface{
    //接口中的成员变量全部都是公共的静态常量,public static final 可以默认不写
    public static final int NUM=20;
    int a=15;
    public abstract void show();
    public abstract void test();
}
class AA implements MyInterface{
    //注意:实现类必须重写接口的所有抽象方法
    @Override
    public void show() {
        //重写接口的show方法
        System.out.println("AA方法的show方法");
    }

    @Override
    public void test() {
        //重写接口的test方法
        System.out.println("AA方法的test方法");
    }
}

补充: jdk1.8之后接口中可以定义一种default修饰方法修饰,default修饰方法时可以给出功能的具体实现

public class Test03 {
    public static void main(String[] args) {
        In in = new In();
        in.show();//实现的show方法
        in.test();//重写过后的test方法
        in.test2();//接口中的default关键字,可以给出功能的具体实现
    }
}

interface Myinterface {
    public abstract void show();

    //接口中的方法使用default修饰,可以给出方法的功能的具体实现
    public default void test() {
        System.out.println("接口中的default关键字,可以给出功能的具体实现");
    }

    public default void test2() {
        System.out.println("接口中的default关键字,可以给出功能的具体实现");
    }
}

class In implements Myinterface {

    @Override
    public void show() {
        System.out.println("实现的show方法");
    }

    @Override
    public void test() {
        System.out.println("重写过后的test方法");
    }
}

5.类与接口之间的关系
(1)类与类:继承关系,可以单继承,可以多继承
(2)类与接口:实现关系,可以单实现,也可以多实现,并且在继承一个类的时候同时实现多个接口
(3)接口与接口:继承关系,可以单继承,也可以多继承

public class Test02 {
    public static void main(String[] args) {
        MyTest test1 = new MyTest();
        test1.aa();//aa
        test1.bb();//bb
        Zi zi = new Zi();
        zi.aa();//ziaa
        zi.bb();//zibb
        zi.cc();//zicc
    }
}
interface AAA{
    public abstract void aa();
}
interface BBB{
    public abstract void bb();
}
//接口可以继承多个接口,并且继承接口的所有抽象方法
interface CCC extends AAA,BBB{
    public abstract void cc();
}
//一个类可以实现多个接口,必须重写实现接口的所有抽象方法
//当有类实现这个接口时,必须重写本身与继承下来的所有抽象方法
class MyTest implements AAA,BBB{

    @Override
    public void aa() {
        System.out.println("aa");
    }

    @Override
    public void bb() {
        System.out.println("bb");
    }
}
class Zi implements CCC{
    @Override
    public void cc() {
        System.out.println("zicc");
    }

    @Override
    public void aa() {
        System.out.println("ziaa");
    }

    @Override
    public void bb() {
        System.out.println("zibb");
    }
}

三、抽象类与接口的区别

 一、成员区别:
      抽象类:成员变量:可以常量,也可以变量
             构造方法:有(抽象类中的构造方法便于子类访问父类数据时的初始化)
             成员方法:可以抽象,也可以非抽象
        接口: 成员变量:只能是常量(public static final)
         	  成员方法:只可以抽象(public abstract)
              构造方法:无
二、关系区别:
		类与类:继承,单继承
		类与接口:实现,单实现和多实现
		接口与接口:继承,单继承与多继承
三、设计理念
		抽象类:被继承体现的是“is  a”的关系,抽象类中定义的是该继承体系的共性功能
		接口:被实现体现的是“like a”的关系,接口中定义的是该继承体系的扩展功能

接口与类的案例:

public class Test04 {
    public static void main(String[] args) {
        //多态形式定义
        Animals animals = new Cat.JiaYangMao();
        animals.name="家养猫";
        animals.age=3;
        System.out.println(animals.name);//家养猫
        System.out.println(animals.age);//3
        animals.eat();//家养猫吃鱼干
        //sleep为特有方法,必须将animals向下转型才可以调用
        Cat.JiaYangMao jiaYangMao= (Cat.JiaYangMao) animals;
        jiaYangMao.sleep();//睡觉
        Cat.ZhaoCaiMao zhaoCaiMao = new Cat.ZhaoCaiMao();
        animals=zhaoCaiMao;
        animals.name="招财猫";
        animals.age=5;
        System.out.println(animals.name);//招财猫
        System.out.println(animals.age);//5
        animals.eat();//招财猫吃猫粮
        //多态定义
        Jump jump=zhaoCaiMao;
        jump.jump();//招财猫学会了跳高
    }
}
//定义一个动物类,里面具有公共的属性
class Animals{
    String name;
    int age;
    public void eat(){
        System.out.println("吃饭");
    }
}
//定义一个接口
interface Jump{
    public abstract void jump();
}
//Cat类继承Animals类,重写eat方法。并且实现jump接口
class Cat extends Animals{
    //重写父类的eat方法
    @Override
    public void eat() {
        System.out.println("猫能够吃鱼");
    }

static class ZhaoCaiMao extends Cat implements Jump{
    @Override
    public void eat() {
        System.out.println("招财猫吃猫粮");
    }
    //重写接口的jump方法
    @Override
    public void jump() {
        System.out.println("招财猫学会了跳高");
    }
}
static class JiaYangMao extends Cat{
    @Override
    public void eat() {
        System.out.println("家养猫吃鱼干");
    }
    //特有方法
    public void sleep(){
        System.out.println("睡觉");
    }
}
}

三、方法参数及返回值类型

3.1 类名作为形式参数

public class Test05 {
    public static void main(String[] args) {
        //类名作为形式参数
        Student student = new Student();
        test(student,200);
        System.out.println(student.num);//200
        student.show(new Student(),300);
        //打印的依旧是第一个对象的num为200
        System.out.println(student.num);//200


    }
    public static void test(Student student,int num){
        student.num=num;
    }
}
class Student{
    int num=100;
    public void show(Student student,int num){
        student.num=num;
        System.out.println("show方法");
    }
}

3.2 抽象类名作为形式参数

当一个方法的参数需要一个抽象类类型时,传入这个抽象类的子类对象。

public class Test06 {
    public static void main(String[] args) {
        //当一个方法的参数需要一个抽象类类型时,传入这个抽象类的子类对象
        //创建一个子类对象
        zilei z = new zilei();
        //test方法传入子类对象一个int类型的值
        test(z,500);
        //子类对象的num值
        System.out.println(z.num);//300

    }
    public static void test(Chouxianglei chouxianglei,int num){
        //父类的num值改变为传入的num值
        chouxianglei.num=num;
        chouxianglei.show(400);
    }
}
abstract class Chouxianglei{
    int num=200;
    public abstract void show(int num);
}
class zilei extends Chouxianglei{
    int num=300;
    @Override
    public void show(int num) {
        //num为传入的参数值
        System.out.println("实现抽象类的show方法"+num);//实现抽象类的show方法400
        //父类的num发生了改变
        System.out.println(super.num);//500
        System.out.println(this.num);//300
    }
}

3.3 接口名作为形式参数

当方法的参数是一个接口时,传入该接口的实现类

public class Test07 {
    public static void main(String[] args) {
        //当方法的参数是一个接口时,传入该接口的实现类
        implementationClass imp1 = new implementationClass();
        test(imp1,300);
        //实现类的num值
        System.out.println(imp1.num);//100
    }
    public static void test(Jiekou jiekou,int num){
        jiekou.show(num);
    }
}
interface Jiekou{
    public static final int NUM=200;
    public abstract void show(int num);

}
class implementationClass implements Jiekou{
    int num=100;
    @Override
    public void show(int num) {
        System.out.println("实现类的show方法"+num);//实现类的show方法300
        System.out.println(this.num);//100
    }
}

3.4 类名作为返回值类型

public class Test02 {
    public static void main(String[] args) {
        //创建一个类的对象
        Student student2 = new Student();
        Student test = test(student2, 200);
        //新建类的对象传参
        System.out.println(student2.num);//200
        System.out.println(test.num);//100
        //this关键字,谁调用谁改变
        student2.show(student2,300);
        System.out.println(student2.num);//300
    }
    public static Student test(Student student,int num){
        student.num=num;
        Student student1 = new Student();
        return student1;
    }
}
class Student{
    int num=100;
    public void show(Student student,int num){
        this.num=num;
    }
}

3.5 抽象类作为返回值类型

当方法的返回值为抽象类时,返回该抽象类的子类对象

public class Test03 {
    public static void main(String[] args) {
        Aclass aclass = test(new Bclass(), 200);
        //返回的是一个抽象类的对象,该对象的num值为抽象类的num
        int num = aclass.num;
        System.out.println(num);//100
        aclass.show(300);
    }
    public static Aclass test(Aclass aclass,int num){
        //方法的返回值为一个抽象类,返回一个该抽象类的子类对象
        aclass.num=num;
        return new Bclass();
    }
}
abstract class Aclass{
    int num=100;
    public abstract void show(int num);
}
class Bclass extends Aclass{
    @Override
    public void show(int num) {
        System.out.println(num);//300
        System.out.println(this.num);//100
        System.out.println(super.num);//100
    }
}

3.6 接口作为返回值类型

接口作为返回值类型,返回该接口的一个实现类

public class Test04 {
    public static void main(String[] args) {
        Myinterface myinter = test(new MyTest(), 500);
        myinter.show(300);//300
    }
    public static Myinterface test(Myinterface myinterface,int num){
        //接口作为返回值类型,返回该接口的一个实现类
        System.out.println(num);//500
        return new MyTest();
    }
}
interface Myinterface{
    public abstract void show(int num);
}
class MyTest implements Myinterface{
    @Override
    public void show(int num) {
        System.out.println(num);
    }
}

你可能感兴趣的:(Java学习,Java语言基础)