Java 语言 / 面向对象进阶(二)

一、抽象类 & 抽象方法

  1. 抽象类
    它是一种特殊的类,不能直接创建对象,而是用于被其他具体类继承。
    要声明一个抽象类,需要使用关键字abstract来修饰类名。如果一个类中包含了至少一个抽象方法,那么这个类就必须声明为抽象类。子类继承抽象类时,必须实现所有抽象方法,除非子类本身也是抽象类。
    理解:抽象类不能被实例化,比如动物这个概念,世界上没有叫“动物”这个东西的物种,不能被具体出来。

  2. 抽象方法
    ● 抽象方法只能有声明,不能有方法实现
    ● 如果类中有抽象方法,那么这个类必须被定义为抽象类;反之未必
    ● 抽象方法只能被定义为 public 或 protected 或 default,不能为 private,因为抽象方法要被继承,定义成private就不能被继承了。
    ● 抽象方法不能是静态的,因为抽象方法是用来定义接口或抽象类中的未实现的方法,而静态方法是属于类而不是对象的方法。抽象方法需要在具体的类中实现或者在继承抽象类的子类中被重写,而静态方法可以直接通过类名进行调用,不需要实例化对象。

抽象方法的一个实例:

    @Test
    public void test01() {
        Dog_day03_1 dog = new Dog_day03_1();
        dog.run();
        dog.eat();
        Cat_day03_1 cat = new Cat_day03_1();
        cat.eat();
    }
}

/**
 * test01 抽象类
 */
abstract class Animal_day03_1 {
   // 非抽象方法,有具体实现
    public void run() {
        System.out.println("The animal is running");
    }

    // 抽象方法只能有声明,不能有方法实现,只能被定义为 public 或 protected 或 default,不能为 private
    public abstract void eat();
}

// 具体类 Dog 继承自抽象类 Animal
class Dog_day03_1 extends Animal_day03_1 {
    @Override
    public void eat() {
        System.out.println("The dog is eating bones");

    }
}

class Cat_day03_1 extends Animal_day03_1 {
    @Override
    public void eat() {
        System.out.println("The cat is eating fish");

    }
}

抽象方法是静态时的情况:

    public void test02() {
        test02_AbstractClass.noabstract_Method(); // 可以直接通过类名调用静态方法,输出“非抽象静态方法”
        // AbstractClass.abstractMethod();  // 报错,无法直接调用抽象方法
    }
}

abstract class test02_AbstractClass {
    // 抽象方法,不能加static,会报错
    // public abstract static void abstract_Method();
    // 非抽象方法,可以加static
    public static void noabstract_Method() {
        System.out.println("非抽象静态方法");
    }
}

二、final

final是一个关键字,用于表示一个不可变的实体。
● 在 Java 中 final 关键字可以被用来修饰类、方法和变量
● 用 final 修饰类时表示此类不可以被继承
● 用 final 修饰方法时表示此方法不可以被继承类覆盖
● 用 final 修饰成员变量时表示该变量是一个常量,在初始化后不能被改变
使用 final 关键字修饰类的静态变量,须在定义时或者在静态块中进行初始化
● 使用 final 关键字修饰类的实例变量,可以在动态块中、也可以在每个构造函数中进行初始化
● 使用 final 关键字修饰方法参数,表示此方法参数不能修改

三、abstract & final

● abstract final 不能同时用来修饰类
● abstract final 不能同时用来修饰方法
● static abstract 不允许。因为抽象方法的调用需要使用方法的动态绑定机制,因此静态方法不能是抽象方法
● private abstract 不允许。因为抽象方法必须要被继承类覆写,因此继承类必须能够访问抽象方法,所以抽象方法的访问权限不能是 private
● 给 abstract 方法赋 default 访问权限,编译允许,但不推荐。因为这样会造成其他包(package)的类无法继承这个抽象类,因为这个抽象方法对其他包(package)的类不可见

/**
 * abstract final 不能同时用来修饰类
 * 这两个关键字矛盾,无法同时用来修饰类
 */

//abstract final class test1 {
//
//}

/**
 * abstract final 不能同时用来修饰方法
 * abstract是抽象方法,需要在子类中进行实现,而final关键字表示方法是最终的,不能被子类重写
 */

//abstract final void test2() {
//
//        }


/**
 * static abstract 不允许
 * 因为抽象方法的调用需要使用方法的动态绑定机制,因此静态方法不能是抽象方法
 */

//class MyClass {
//    public static abstract void test3() {
//
//    }
//}


/**
 * private abstract 不允许
 * 因为抽象方法必须要被继承类覆写,因此继承类必须能够访问抽象方法,所以抽象方法的访问权限不能是 private
 */

//abstract class test4 {
//    private abstract void privateAbstractMethod();
//}

/**
 * 给抽象方法赋予 default 访问权限,编译允许但不推荐
 */

abstract class test5 {
    abstract void defaultAbstractMethod();
}

四、接口

接口概念
是Java中一种抽象的编程结构,它定义了一组方法的规范,但没有提供方法的具体实现。接口可以被看作是没有实例数据,并且所有方法都是抽象方法的抽象类。

接口继承
接口之间也可以继承,而且一个接口可以从多个接口继承。

接口实现:

  @Test
    public void test03() {
        //Animal_interface_test03 dog = new Dog_interface_test03();
        Dog_interface_test03 dog = new Dog_interface_test03();
        dog.eat();
        Bird_interface_test03 bird = new Bird_interface_test03();
        bird.fly();
        bird.eat();
        System.out.println(bird.age);
        }

// 接口简单实现
interface Animal_interface_test03 {
    // protected void eat(); // 使用protected会报错 Modifier 'protected' not allowed here
    void eat();
    int age = 10;
}

interface Plane_interface_test03 {
    void fly();
}

class Dog_interface_test03 implements Animal_interface_test03 {
    public void eat(){
        System.out.println("The dog is eating bones");
    }
}

// 多继承
class Bird_interface_test03 implements Animal_interface_test03, Plane_interface_test03 {
    public void eat() {
        System.out.println("The bird is eating rice");
    }
    public void fly() {
        System.out.println("The bird is flying");
    }
}

在Java早期版本(Java 7及之前),接口中不能包含静态方法。从Java 8开始,引入了接口中的静态方法的概念。Java 8以后的版本允许在接口中定义静态方法,以提供更多的灵活性和实用性。使用时,静态方法不能被实例化对象调用,而应该通过接口名来调用。

   public void test04() {
        Dog_interface_test04 dog = new Dog_interface_test04();
        dog.eat(); // 狗吃骨头,这是非静态方法
        // dog.run(); // 这个是静态方法,静态方法不能被实例化对象调用,而应该通过接口名来调用。
        Animal_interface_test04.run(); // 动物跑,这是静态方法,静态方法不能被实例化对象调用,而应该通过接口名来调用。
    }

interface Animal_interface_test04 {
    //
    void eat();
    static void run(){
        System.out.println("动物跑,这是静态方法");
    }
}

class Dog_interface_test04 {
    void eat(){
        System.out.println("狗吃骨头,这是非静态方法");
    }
}

抽象类和接口的区别
继承关系:抽象类使用extends关键字进行继承,而接口使用implements关键字进行实现。一个类只能继承一个抽象类,但可以实现多个接口。
实现方法:抽象类可以包含非抽象方法,也可以包含成员变量和构造函数,而接口只能包含抽象方法和常量(默认是public static final类型的)。因此,抽象类提供了部分实现,子类只需要实现抽象方法即可,而接口要求实现类提供完整的实现。
关系类型:抽象类是一种类的继承关系,用于表示类的共性特征,它不能被实例化。接口是一种更为抽象的规范,用于定义类应该具备的行为或功能,实现接口的类可以属于不同的继承关系。

代码示例:

    public void test05() {
        Bird_test05 bird = new Bird_test05();
        bird.call();
        bird.fly();
        bird.sleep(); // 非静态方法可以直接被调用
        // 输出:小鸟喳喳叫
        //      小鸟嗷嗷飞
        //      动物在睡觉
    }

// 抽象类
abstract class Animal_test05 {
    public abstract void call();
    public void sleep() {
        System.out.println("动物在睡觉");
    }
}

//接口
interface Fly_test05{
    void fly();
}

class Bird_test05 extends Animal_test05 implements Fly_test05{

    @Override
    public void call() {
        System.out.println("小鸟喳喳叫");
    }

    @Override
    public void fly() {
        System.out.println("小鸟嗷嗷飞");
    }
}

五、内部类

1.静态内部类(Static inner class)
定义在类的内部,并且被声明为static的内部类。

2.成员内部类(Member inner class)
定义在类的内部,且不是static的内部类。

3.本地内部类(Local inner class)
定义在方法内部的类,作用范围仅限于方法内部。

4.匿名内部类(Anonymous inner class)
没有名字的内部类,用于定义只使用一次的类。

public class OuterClass {
    private int outerField;

    // 成员内部类
    public class MemberInnerClass {
        public void innerMethod() {
            System.out.println("Member Inner Class method");
        }
    }

    // 局部内部类
    public void localInnerClassMethod() {
        class LocalInnerClass {
            public void innerMethod() {
                System.out.println("Local Inner Class method");
            }
        }
        LocalInnerClass inner = new LocalInnerClass();
        inner.innerMethod();
    }

    // 匿名内部类
    public void anonymousInnerClassMethod() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Anonymous Inner Class method");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    // 静态内部类
    public static class StaticInnerClass {
        public void innerMethod() {
            System.out.println("Static Inner Class method");
        }
    }

    public static void main(String[] args) {
        OuterClass outer = new OuterClass();

        // 访问成员内部类
        MemberInnerClass memberInner = outer.new MemberInnerClass();
        memberInner.innerMethod();

        // 访问局部内部类
        outer.localInnerClassMethod();

        // 访问匿名内部类
        outer.anonymousInnerClassMethod();

        // 访问静态内部类
        StaticInnerClass staticInner = new StaticInnerClass();
        staticInner.innerMethod();
    }
}

六、Java Bean

Java Bean常用于封装数据,并提供公共的getter和setter方法来访问和修改数据。

代码示例:

   public void test08() {
        Animal_Bean cat = new Animal_Bean();
        cat.set_Name("咪咪");
        cat.set_Age(5);
        Animal_Bean dog = new Animal_Bean();
        dog.set_Name("旺财");
        dog.set_Age(3);
        System.out.println("小猫叫" + cat.get_Name() + ", 年龄" + cat.get_Age());
        System.out.println("小狗叫" + dog.get_Name() + ", 年龄" + dog.get_Age());
    }
    // 输出:
    //     小猫叫咪咪, 年龄5
    //     小狗叫旺财, 年龄3

class Animal_Bean {
    private String name;
    private int age;
    public Animal_Bean() {
        // 无参构造函数
    }
    public String get_Name() {
        return name;
    }
    public void set_Name(String name) {
        this.name = name;
    }
    public int get_Age() {
        return age;
    }
    public void set_Age(int age) {
        this.age = age;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值