面向对象基础

本文详细介绍了面向对象编程中的关键概念,如类的继承、构造子类的super调用、抽象类与接口的使用、final关键字的应用,以及静态字段、静态方法和内部类(包括匿名类和静态内部类)的特性。这些内容有助于理解Java中类和接口的设计原则,提高代码的灵活性和可维护性。
摘要由CSDN通过智能技术生成

面向对象基础

继承

  1. 构造子类方法时必须加上super();括号内参数就是父类构造方法所需参数

    class Student extends Person {
        protected int score;
    
        public Student(String name, int age, int score) {
            super(name, age); // 调用父类的构造方法Person(String, int)
            this.score = score;
        }
    }
    
  2. 在子类的覆写(override)方法中,如果要调用父类的被覆写的方法,可以通过super来调用。例如:

    class Person {
        protected String name;
        public String hello() {
            return "Hello, " + name;
        }
    }
    
    class Student extends Person {
        @Override
        public String hello() {
            // 调用父类的hello()方法:
            return super.hello() + "!";
        }
    }
    

final

  • final关键字保证子类不能override父类的方法:

​ e.g. public final String hello()

  • 还可以final直接规定不可继承父类

​ e.g. final class person{}

  • 对于一个类的实例字段,同样可以用final修饰。用final修饰的字段在初始化后不能被修改。

​ e.g. public final String name = "Unamed";

  • final字段重新赋值会报错:
Person p = new Person();
p.name = "New Name"; // compile error!

抽象类

如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法:

class Person {
    public abstract void run();
}
  • 这是一个抽象方法,只需要声明,不用执行语句

  • 正确编译需要将父类声明为abstract

    abstract class Person{
        public abstract void run();
    }
    
  • 抽象类无法实例化,也就是不能创建对象

    Person p = new Person(); // 编译错误
    
  • 抽象类只能用于继承

面向抽象编程

当我们定义了抽象类Person,以及具体的StudentTeacher子类的时候,我们可以通过抽象类Person类型去引用具体的子类的实例:

Person s = new Student();
Person t = new Teacher();

interface 接口

在Java中,使用interface可以声明一个接口:

interface Person {
    void run();
    String getName();
}
  • 所谓interface,就是比抽象类还要抽象的纯抽象接口,因为它连字段都不能有。因为接口定义的所有方法默认都是public abstract的,所以这两个修饰符不需要写出来(写不写效果都一样)。

  • 当一个具体的class去实现一个interface时,需要使用implements关键字。

    class Student implements Person {...}
    
  • 我们知道,在Java中,一个类只能继承自另一个类,不能从多个类继承。但是,一个类可以实现多个interface,例如:

    class Student implements Person, Hello { // 实现了两个interface
        ...
    }
    
    • 降低类之间的耦合度
    • 避免单继承的限制

接口继承

  • 一个interface可以继承自另一个interfaceinterface继承自interface使用extends,它相当于扩展了接口的方法。

静态字段与静态方法

静态字段

浅显理解:不管多少个对象,公用一个静态字段,一个变全变

  • 静态字段是属于类而不是对象的,所有实例共享一个静态字段
  • 对静态字段的访问,好的方法是类名.静态字段,不推荐用实例变量.静态字段去访问静态字段

静态方法

调用实例方法必须通过一个实例变量,而调用静态方法则不需要实例变量,通过类名就可以调用。静态方法类似其它编程语言的函数。例如Person.run()

  • 因为静态方法属于class而不属于实例,因此,静态方法内部,无法访问this变量,也无法访问实例字段,它只能访问静态字段。

接口的静态字段

因为interface是一个纯抽象类,所以它不能定义实例字段。但是,interface是可以有静态字段的,并且**静态字段必须为final**类型:

public interface Person {
    public static final int MALE = 1;
    public static final int FEMALE = 2;
}

实际上,因为interface的字段只能是public static final类型,所以我们可以把这些修饰符都去掉


作用域

1. public

  1. public 类,可以被任何其他类访问,甚至不是同一个package

    package abc;
    
    public class Hello {
        public void hi() {
        }
    }
    

    上面的Hellopublic,因此,可以被其他包的类访问:

    package xyz;
    
    class Main {
        void foo() {
            // Main可以访问Hello
            Hello h = new Hello();
        }
    }
    

    但是,定义为publicfieldmethod可以被其他类访问,前提是首先有访问class的权限:


2. private

  1. 定义为privatefieldmethod无法被其他类访问
  2. 由于Java支持嵌套类nested class,如果一个类内部还定义了嵌套类,那么,嵌套类拥有访问private的权限.

3. protected

  1. protected作用于继承关系。定义为protected的字段和方法可以被子类访问,以及子类的子类

4. default

​ 同一个包内正常访问


内部类

1. Inner class

class Outer {
    private String name;
    Outer(String name) {
        this.name = name;
    }

    class Inner {
        void hello() {
            System.out.println("Hello, " + Outer.this.name);
        }
    }
}

new一个新的Inner对象时,要实例化一个Inner,我们必须首先创建一个Outer的实例,然后,调用Outer实例的new来创建Inner实例:

Outer outer = new Outer("Nested"); // 实例化一个Outer
Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
  • Inner Class和普通Class相比,除了能引用Outer实例外,还有一个额外的“特权”,就是可以修改Outer Class的private字段,因为Inner Class的作用域在Outer Class内部,所以能访问Outer Class的private字段和方法。

2. 匿名类

匿名类就是没有使用class关键字声明定义的类,也就相当于并没有给这个类启用一个可以全局调用的名字

  • 不完全理解

3. 静态内部类(Static Nested Class)

class Outer {
    private static String NAME = "OUTER";

    private String name;

    Outer(String name) {
        this.name = name;
    }

    static class StaticNested {
        void hello() {
            System.out.println("Hello, " + Outer.NAME);
        }
    }
}

static修饰的内部类和Inner Class有很大的不同,它不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this,但它可以访问Outerprivate静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。

内部类的优势在于,可以访问外部类及其父类的方法和属性。因为java的类只能继承自一个父类,通过内部类,相当于可以同时继承外部类的父类和自己的父类,也就是继承两个父类。

匿名内部类简化了内部类的继承与创建对象的写法

通过 new SuperClass() {...}等同于创建了一个继承自SuperClass父类的匿名子类的对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值