类的声明

package com.mek.demo;

public class Person {
    
}

类属性与类方法

package com.mek.demo;

public class Person {
    // public 公开属性 可以被外部访问
    public String name;
    // private 私有属性 无法被外部访问
    private int money;
    
    // 公共方法
    public void setName(String name) {
        this.name = name;
    }
    // 公共方法
    public String getName() {
        return this.name;
    }
    // 私有方法
    private void sey(String text) {
        System.out.println(text);
    }

}

创建类

package com.mek.demo;

public class Main {
    public static void main(String[] args) {
        // 通过new 创建Person的实例对象
        Person p = new Person();

    }

}

类的继承

package com.mek.demo;

public class Person {
    // public 公开属性 可以被外部访问
    public String name;
    // private 私有属性 无法被外部访问
    private int money;

    // 公共方法
    public void setName(String name) {
        this.name = name;
    }

    // 公共方法
    public String getName() {
        return this.name;
    }



    // 私有方法
    private void sey(String text) {
        System.out.println(text);
    }

}

class Employee extends Person {
    /*

    类的继承 使用 "extends" 关键字
    无法继承父类的私有属性和方法
     */
    private int money;

    public void getMoney(int money) {
        this.money += money;
    }
    public void printMoney(){
        System.out.println(this.money);
    }
}

类构造器

package com.mek.demo;

public class Person {
    /*
    public Person() 类的构造器,实例对象被创建时执行,可以被重载
    */
    public Person(){
        System.out.println("创建了一个Person");
    }
    public Person(String name){
        System.out.println("创建了一个Person");
        this.name = name;
    }
    public Person(String name,int money){
        System.out.println("创建了一个Person");
        this.name = name;
        this.money = money;
    }

    // public 公开属性 可以被外部访问
    public String name;
    // private 私有属性 无法被外部访问
    private int money;

    // 公共方法
    public void setName(String name) {
        this.name = name;
    }

    // 公共方法
    public String getName() {
        return this.name;
    }

    public void printMoney(){
        System.out.println(this.money);
    }

    // 私有方法
    private void sey(String text) {
        System.out.println(text);
    }

}

super

在Java中,super 是一个关键字,用于引用当前子类所继承的父类的成员(方法和属性)。它可以用于以下几个方面:

  1. 调用父类的构造方法:当子类的构造方法被调用时,可以使用 super() 关键字来调用父类的构造方法。这样可以在子类的构造方法中执行父类的初始化操作。

    public class SubClass extends SuperClass {
        public SubClass() {
            super(); // 调用父类的构造方法
        }
    }
    

    在上述代码中,super() 表示调用了父类的无参构造方法。如果父类有参数的构造方法,可以根据需要传递参数。

  2. 访问父类的成员:当子类中存在与父类同名的成员(方法或属性)时,可以使用 super 关键字来引用父类的成员,以区分子类和父类的同名成员。

    public class SubClass extends SuperClass {
        private int x;
    
        public void setX(int x) {
            super.x = x; // 引用父类的属性
        }
    
        public void printX() {
            System.out.println(super.x); // 引用父类的属性
        }
    
        public void printMessage() {
            super.printMessage(); // 调用父类的方法
            System.out.println("This is the sub class."); // 子类自己的逻辑
        }
    }
    

    在上述代码中,super.x 引用了父类的属性 xsuper.printMessage() 调用了父类的方法 printMessage()

注意事项:

  • super() 必须作为子类构造方法的第一条语句使用,且仅用于构造方法中。
  • super 关键字只能在子类中使用,用于引用父类的成员。
  • super 关键字不能用于静态方法或静态代码块中,因为它们与实例化对象无关。只能用于实例方法(非静态方法)中。

通过使用 super 关键字,我们可以在子类中方便地调用父类的构造方法和访问父类的成员,实现对继承关系中父类的控制和使用。

类方法的重写

类方法重写(Method Overriding)是面向对象编程中的一个概念,它允许子类重新定义父类中已经存在的方法。当子类重写一个父类的方法时,子类提供了一个具有相同名称、相同参数列表和相同返回类型的新实现。

重写方法的目的是允许子类在继承父类的方法基础上修改或定制其行为,以满足特定的需求。子类可以根据自己的需要改变方法的实现逻辑,但方法的签名(名称、参数列表和返回类型)必须与父类方法保持一致。

在Java中,要重写一个方法,需要满足以下条件:

  1. 子类的方法名、参数列表和返回类型必须与父类的方法相同。
  2. 子类方法的访问修饰符不能比父类方法更严格。例如,如果父类方法是public,子类方法可以是public或者protected,但不能是private
  3. 子类方法不能抛出比父类方法更多的异常,或者抛出未在父类方法中声明的异常。

下面是一个简单的示例代码,演示了方法重写的概念:

class Animal {
    public void makeSound() {
        System.out.println("Animal is making a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.makeSound(); // 输出:Animal is making a sound
        
        Dog dog = new Dog();
        dog.makeSound(); // 输出:Dog is barking
    }
}

在上面的示例中,Animal类有一个名为makeSound()的方法,而Dog类继承了Animal类并重写了makeSound()方法。当我们创建一个Dog对象并调用makeSound()方法时,输出的结果是"Dog is barking",而不是"Animal is making a sound",这是因为子类重写了父类的方法,提供了新的实现逻辑。

多态

多态(Polymorphism)是面向对象编程中的一个重要概念,它允许使用不同的方式来处理不同的数据类型或对象。简而言之,多态性允许我们使用父类的引用变量来引用子类的对象。

多态性的关键概念是方法的重写和方法的动态绑定。当一个父类的引用变量引用一个子类的对象时,可以根据实际的对象类型,在运行时决定调用哪个类的方法。

通过多态性,我们可以编写通用的代码,可以处理多个不同的对象类型,而不需要为每个具体的对象类型编写特定的代码。

以下是一个示例,演示多态的概念:

class Animal {
    public void makeSound() {
        System.out.println("Animal is making a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog is barking");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat is meowing");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        animal1.makeSound(); // 输出:Dog is barking
        animal2.makeSound(); // 输出:Cat is meowing
    }
}

在上面的示例中,Animal类是一个父类,而DogCat是其子类。在main方法中,我们创建了一个Animal类型的引用变量animal1,它引用了一个Dog对象,还创建了一个Animal类型的引用变量animal2,它引用了一个Cat对象。

当我们调用animal1.makeSound()时,由于animal1引用的对象是Dog类型,所以实际调用的是Dog类重写的makeSound()方法,输出的结果是"Dog is barking"。

同样地,当我们调用animal2.makeSound()时,由于animal2引用的对象是Cat类型,所以实际调用的是Cat类重写的makeSound()方法,输出的结果是"Cat is meowing"。

这就是多态性的体现,相同的方法调用可以在不同的对象上产生不同的结果,根据实际对象的类型来确定具体调用哪个类的方法。这样,我们可以通过父类的引用变量来统一处理不同子类的对象,提高代码的灵活性和可扩展性。

Instanceof

instanceof 是 Java 中的一个运算符,用于检查对象是否属于某个类或其子类的实例。它的语法形式是 object instanceof class,其中 object 是待检查的对象,class 是要检查的类或接口。

instanceof 运算符的返回结果是一个布尔值,如果 objectclass 的实例或者 class 的子类的实例,返回 true;否则返回 false

以下是一个示例,展示了 instanceof 运算符的使用:

class Animal {
    // ...
}

class Dog extends Animal {
    // ...
}

class Cat extends Animal {
    // ...
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();
        
        System.out.println(animal instanceof Animal); // 输出:true
        System.out.println(animal instanceof Dog);    // 输出:true
        System.out.println(animal instanceof Cat);    // 输出:false
    }
}

在上面的示例中,我们有一个 Animal 类和它的两个子类 DogCat。在 main 方法中,我们创建了一个 Animal 类型的引用变量 animal,它引用了一个 Dog 对象。

通过 animal instanceof Animal,我们检查 animal 是否是 Animal 类的实例,结果是 true,因为 animal 实际上是 Animal 类的子类 Dog 的实例。

同样地,animal instanceof Dog 的结果也是 true,因为 animalDog 类的实例。

然而,animal instanceof Cat 的结果是 false,因为 animal 不是 Cat 类的实例。

instanceof 运算符可以帮助我们在运行时动态地确定对象的类型,从而进行相应的处理。它在编写代码时经常用于类型检查和类型转换,以增加代码的灵活性和安全性。

抽象类

当我们在Java中定义一个类时,可以使用关键字 abstract 来声明一个抽象类。抽象类是一个不能被实例化的类,它主要用作其他类的基类,提供了一种用于继承和组织相关子类的机制。

抽象类具有以下特点:

  1. 无法被实例化:不能直接创建抽象类的实例,因为它是不完整的,其中可能包含抽象方法或没有实现的方法。只能通过创建其子类的实例来间接使用抽象类。
  2. 可以包含抽象方法:抽象方法是没有实现体的方法,只有方法声明而没有具体的实现。子类必须实现(覆盖)抽象类中的所有抽象方法,否则子类也必须声明为抽象类。
  3. 可以包含非抽象方法:抽象类除了可以包含抽象方法外,还可以包含非抽象的普通方法,这些方法具有具体的实现。
  4. 可以包含成员变量和构造方法:抽象类可以拥有成员变量和构造方法,用于存储和初始化对象的状态。
  5. 可以被继承:其他类可以通过继承抽象类来扩展其功能,子类必须实现父类中的抽象方法。

以下是一个简单的抽象类的示例:

abstract class Animal {
    String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    public abstract void makeSound();
    
    public void eat() {
        System.out.println(name + " is eating");
    }
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog("Bobby");
        animal.makeSound(); // 输出:Bobby is barking
        animal.eat();       // 输出:Bobby is eating
    }
}

在上面的示例中,Animal 是一个抽象类,它包含了一个抽象方法 makeSound() 和一个非抽象方法 eat(),以及一个成员变量 nameAnimal 类的构造方法用于初始化 name 属性。

Dog 类继承了 Animal 类并实现了 makeSound() 方法。在 main 方法中,我们创建了一个 Dog 对象,并将其赋值给 Animal 类型的变量 animal。通过这种方式,我们可以使用抽象类的引用来操作子类对象。

当我们调用 animal.makeSound() 时,实际上调用的是 Dog 类中重写的 makeSound() 方法,输出的结果是"Bobby is barking"。而调用 animal.eat() 方法时,由于 Animal 类中定义了具体的实现,所以输出的结果是"Bobby is eating"。

通过抽象类的使用,我们可以定义一个通用的父类,其中包含了共享的属性和行为,同时规定了子类必须实现的抽象方法。这样,我们可以通过抽象类来实现代码的重用和扩展,同时约束了子类的实现。