第3天

2023/6/15

# 第3天

复习

Java 作为一种面向对象的编程语言,支持以下基本概念:

1、类(Class):

定义对象的蓝图,包括属性和方法。

示例:public class Car { ... }

2、对象(Object):

类的实例,具有状态和行为。

示例:Car myCar = new Car();

3、继承(Inheritance):

一个类可以继承另一个类的属性和方法。

示例:public class Dog extends Animal { ... }

4、封装(Encapsulation):

将对象的状态(字段)私有化,通过公共方法访问。

示例:

private String name; 
public String getName() { return name; }

5、多态(Polymorphism):

对象可以表现为多种形态,主要通过方法重载方法重写实现。

示例:

方法重载:public int add(int a, int b) { ... } 和 public double add(double a, double b) { ... }

方法重写:@Override public void makeSound() { System.out.println("Meow"); }

6、抽象(Abstraction):

使用抽象类和接口来定义必须实现的方法,不提供具体实现。

示例:

抽象类:public abstract class Shape { abstract void draw(); }

接口:public interface Animal { void eat(); }

7、接口(Interface):

定义类必须实现的方法,支持多重继承。

示例:public interface Drivable { void drive(); }

8、方法(Method):

定义类的行为,包含在类中的函数。

示例:public void displayInfo() { System.out.println("Info"); }

9、方法重载(Method Overloading):

同一个类中可以有多个同名的方法,但参数不同。

示例:

定义了一个名为 MathUtils 的公共类,其中包含两个重载的 add 方法。

//public class MathUtils 定义了一个名为 MathUtils 的公共类。公共类可以被其他类访问。
//public int add(int a, int b) 定义了一个公共方法 add,该方法接受两个整数参数 a 和 b,并返回它们的和。
//return a + b; 返回两个整数参数的和。
//public double add(double a, double b) 定义了一个公共方法 add,该方法接受两个双精度浮点数参数 a 和 b,并返回它们的和。
//return a + b; 返回两个双精度浮点数参数的和。
public class MathUtils {
    public int add(int a, int b) {
        return a + b;
    }

    public double add(double a, double b) {
        return a + b;
    }
}

该类通过方法重载实现了对不同数据类型(整数和浮点数)的加法运算。

方法重载允许同一个类中存在多个同名方法,但它们的参数列表必须不同(参数的数量或类型不同)。

# 注意事项

  1. 使用方法重载时,需要注意参数的类型和数量,以确保方法调用时能够正确匹配到相应的重载方法。
  2. 在实际应用中,可能需要考虑异常处理,例如参数为 null 的情况,但在这个示例中并没有处理。
  3. 如果需要支持更多数据类型,可以继续添加相应的方法重载。

对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。

类:类是一个模板,它描述一类对象的行为和状态。

男孩(boy)、女孩(girl)为类(class),而具体的每个人为该类的对象(object)

img_13.png

一个类可以包含以下类型变量:

  • 局部变量:在方法、构造方法或语句块中定义的变量。
  • 成员变量:在类中定义的变量。
  • 常量:使用 final 关键字声明的变量。
  • 实例变量:在类中定义的变量,但在方法、构造方法或语句块之外。
  • 类变量:使用 static 关键字声明的变量,类变量也称为静态变量,它们在类加载时初始化,并且在所有实例之间共享。

示例:

# 成员变量

  1. 实例变量 myPrivateVar:
  • 类型:int
  • 访问修饰符:private
  • 作用域:仅限于类的实例,不能被类本身直接访问。
  • 初始化:通过构造函数 MyClass(int value) 进行初始化。
  1. 类变量 myPublicStaticVar:
  • 类型:int
  • 访问修饰符:public
  • 修饰符:static
  • 作用域:属于类本身,而不是类的实例。所有类的实例共享这个变量。
  • 初始化:通过静态方法 setMyPublicStaticVar(int value) 进行初始化。

# 构造函数

public MyClass(int value):

  • 这是一个构造函数,用于创建 MyClass 类的实例,并初始化实例变量 myPrivateVar。
//定义了一个名为 MyClass 的 Java 类,它包含两个成员变量(一个实例变量和一个类变量),以及一些用于访问和修改这些变量的方法。
public class MyClass {
    private int myPrivateVar; // 实例变量
    public static int myPublicStaticVar; // 类变量

    public MyClass(int value) {
        this.myPrivateVar = value;
    }

    public int getMyPrivateVar() {
        return myPrivateVar;
    }

    public static void setMyPublicStaticVar(int value) {
        myPublicStaticVar = value;
    }

    public static int getMyPublicStaticVar() {
        return myPublicStaticVar;
    }
}

# 方法

  1. getMyPrivateVar():
  • 这是一个实例方法,用于获取实例变量 myPrivateVar 的值。
  • 返回类型:int
  • 访问修饰符:public
  • 作用域:可以被类的实例调用。
  1. setMyPublicStaticVar(int value):
  • 这是一个静态方法,用于设置类变量 myPublicStaticVar 的值。
  • 参数:int value
  • 返回类型:void
  • 访问修饰符:public
  • 作用域:可以被类的任何实例或类本身调用。
  1. getMyPublicStaticVar():
  • 这是一个静态方法,用于获取类变量 myPublicStaticVar 的值。
  • 返回类型:int
  • 访问修饰符:public
  • 作用域:可以被类的任何实例或类本身调用。

# 笔记

  • private 修饰符确保了实例变量 myPrivateVar 的封装性,只能通过类内部的方法来访问和修改。
  • public 修饰符确保了类变量 myPublicStaticVar 可以被外部类访问。
  • static 修饰符使得类变量 myPublicStaticVar 与类的实例无关,而是属于类本身。
  • 构造函数用于初始化实例变量,而静态方法用于初始化和访问类变量。

局部变量,示例

//public:这是访问修饰符,表示这个类可以被任何其他类访问。
//class:这是定义类的关键字。
//MyClass:这是类的名称,按照Java的命名规范,类名通常使用大驼峰命名法。

//int:这是变量的数据类型,表示这是一个整数类型。
//myLocalVar:这是变量的名称,按照Java的命名规范,变量名通常使用小驼峰命名法。
//= 10:这是变量的初始化,表示将变量 myLocalVar 初始化为10。

//System.out.println:这是Java中的一个标准输出方法,用于在控制台打印输出。
//myLocalVar:这是要打印的变量,这里打印的是 myLocalVar 的值。
public class MyClass {
    public void myMethod() {
        int myLocalVar = 10; // 局部变量
        System.out.println(myLocalVar);
    }
}

# 笔记

  • 局部变量只在定义它的方法内可见,方法结束后局部变量会被销毁。
  • Java的命名规范要求类名使用大驼峰命名法,方法名和变量名使用小驼峰命名法。
  • 注释有助于提高代码的可读性和可维护性,但不应包含任何会影响程序执行的代码。

常量,示例

//public static final int MY_CONSTANT = 10;:定义了一个名为MY_CONSTANT的常量,类型为int,值为10。public表示该常量可以被其他类访问,static表示该常量属于类本身而不是类的实例,final表示该常量的值在初始化后不能被修改。
public class MyClass {
    public static final int MY_CONSTANT = 10; // 常量

    public static void main(String[] args) {
        System.out.println(MyClass.MY_CONSTANT);
    }
}
//public static void main(String[] args):定义了Java应用程序的入口点。public表示该方法可以被其他类访问,static表示该方法属于类本身而不是类的实例,void表示该方法没有返回值,main是方法名,String[] args是方法的参数,用于接收命令行参数。
//  System.out.println(MyClass.MY_CONSTANT);:使用System.out.println方法打印常量MY_CONSTANT的值。MyClass.MY_CONSTANT表示访问MyClass类中的MY_CONSTANT常量。

# 笔记

  • 常量名通常使用全大写字母,单词之间用下划线分隔,以增加可读性。
  • 常量一旦被定义,其值就不能被修改。
  • 常量通常用于表示程序中的固定值,如数学常数、配置参数等。

方法,示例

public class MyClass {
    public void myMethod() {
        System.out.println("Hello, World!");
    }

    public int add(int a, int b) { // 方法
        return a + b;
    }
}

构造方法,示例

public class MyClass {
    private int myVar;

    public MyClass(int value) {
        this.myVar = value;
    }

    public int getMyVar() {
        return myVar;
    }
}

访问修饰符,示例

public class MyClass {
    private int myPrivateVar; // 私有变量
    public int myPublicVar; // 公共变量

    public void myMethod() {
        System.out.println("Hello, World!");
    }
}

成员变量,示例

public class MyClass {
    private int myVar; // 成员变量

    public MyClass(int value) {
        this.myVar = value;
    }

    public int getMyVar() {
        return myVar;
    }
}

类变量,示例

public class MyClass {
    public static int myVar; // 类变量

    public static void main(String[] args) {
        MyClass.myVar = 10;
        System.out.println(MyClass.myVar);
    }
}

# 构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

构造方法可以带有参数,也可以不带参数。构造方法的基本形式如下:

public class MyClass {
    private int myVar;

    public MyClass(int value) {
        this.myVar = value;
    }

    public int getMyVar() {
        return myVar;
    }
}
public class Puppy{
   public Puppy(String name){
      //这个构造器仅有一个参数:name
      System.out.println("名字是 : " + name ); 
   }
   public static void main(String[] args){
      // 下面的语句将创建一个Puppy对象
      Puppy myPuppy = new Puppy( "吃鱼不挑刺" );
   }
}

# 访问修饰符

Java 提供了以下四种访问修饰符:

  • default:默认,不使用任何关键字。
  • private:私有的,只能在当前类中访问。
  • protected:受保护的,可以在当前类、同一个包中的类以及不同包中的子类中访问。
  • public:公共的,可以在任何地方访问。

# 访问实例变量和方法

/* 实例化对象 */
Object referenceVariable = new Constructor();
/* 访问类中的变量 */
referenceVariable.variableName;
/* 访问类中的方法 */
referenceVariable.methodName();

通过已创建的对象来访问成员变量和成员方法,示例

public class MyClass {
    private int myVar;

    public MyClass(int value) {
        this.myVar = value;
    }

    public int getMyVar() {
        return myVar;
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass myObject = new MyClass(10);
        System.out.println(myObject.getMyVar());
    }
}

# 继承

继承是面向对象编程的一个基本概念,它允许我们定义一个类(子类)继承另一个类(父类)的属性和方法。

继承的语法如下:

public class 子类 extends 父类 {
    // 子类的代码
}

示例:

public class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

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

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat(); // 调用父类的方法
        myDog.bark(); // 调用子类的方法
    }
}

# 多态

多态是面向对象编程的一个基本概念,它允许我们定义一个类(子类)继承另一个类(父类)的属性和方法。

多态的语法如下:

public class 子类 extends 父类 {
    // 子类的代码
}

示例:

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

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

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

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Animal();  // 创建一个Animal对象
        Animal myDog = new Dog();        // 创建一个Dog对象
        Animal myCat = new Cat();        // 创建一个Cat对象
        myAnimal.makeSound();            // 调用Animal的makeSound方法
        myDog.makeSound();               // 调用Dog的makeSound方法
        myCat.makeSound();               // 调用Cat的makeSound方法
    }
}

实例

下面的例子展示如何访问实例变量和调用成员方法:

public class Puppy {
    private int age;
    private String name;
 
    // 构造器
    public Puppy(String name) {
        this.name = name;
        System.out.println("小狗的名字是 : " + name);
    }
 
    // 设置 age 的值
    public void setAge(int age) {
        this.age = age;
    }
 
    // 获取 age 的值
    public int getAge() {
        return age;
    }
 
    // 获取 name 的值
    public String getName() {
        return name;
    }
 
    // 主方法
    public static void main(String[] args) {
        // 创建对象
        Puppy myPuppy = new Puppy("Tommy");
 
        // 通过方法来设定 age
        myPuppy.setAge(2);
 
        // 调用另一个方法获取 age
        int age = myPuppy.getAge();
        System.out.println("小狗的年龄为 : " + age);
 
        // 也可以直接访问成员变量(通过 getter 方法)
        System.out.println("变量值 : " + myPuppy.getAge());
    }
}


编译并运行上面的程序,产生如下结果:

小狗的名字是 : tommy
小狗的年龄为 : 2
变量值 : 2

# 源文件声明规则

  • 一个源文件中只能有一个 public 类
  • 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为 Employee.java。
  • 如果源文件中只有一个没有 public 修饰的类,那么源文件的名称可以是任意的,比如 MyEmployee.java。
  • 一个源文件可以有多个非 public 类,也可以有 public 类。如果有 public 类,那么源文件的名称应该和 public 类的类名保持一致。
  • 源文件中 public 类的访问修饰符只能是 public 或者默认的包访问权限,不能是 private 或者 protected。

# 规则

  1. 一个源文件中只能有一个 public 类
  2. 一个源文件可以有多个非 public 类
  3. 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
  4. 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
  5. 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
  6. import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

# Java 包

包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

# import 语句

在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类

import java.io.*;

# 简单的例子

Employee.java 文件代码:

import java.io.*;
 
public class Employee {
    private String name;
    private int age;
    private String designation;
    private double salary;
 
    // Employee 类的构造器
    public Employee(String name) {
        this.name = name;
    }
 
    // 设置 age 的值
    public void setAge(int age) {
        this.age = age;
    }
 
    // 获取 age 的值
    public int getAge() {
        return age;
    }
 
    // 设置 designation 的值
    public void setDesignation(String designation) {
        this.designation = designation;
    }
 
    // 获取 designation 的值
    public String getDesignation() {
        return designation;
    }
 
    // 设置 salary 的值
    public void setSalary(double salary) {
        this.salary = salary;
    }
 
    // 获取 salary 的值
    public double getSalary() {
        return salary;
    }
 
    // 打印信息
    public void printEmployee() {
        System.out.println(this);
    }
 
    // 重写 toString 方法
    @Override
    public String toString() {
        return "名字: " + name + "\n" +
               "年龄: " + age + "\n" +
               "职位: " + designation + "\n" +
               "薪水: " + salary;
    }
}

EmployeeTest.java 文件代码:

import java.io.*;
 
public class EmployeeTest {
    public static void main(String[] args) {
        // 使用构造器创建两个对象
        Employee empOne = new Employee("Da1");
        Employee empTwo = new Employee("Da2");
 
        // 调用这两个对象的成员方法
        empOne.setAge(26);
        empOne.setDesignation("高级程序员");
        empOne.setSalary(1000);
        empOne.printEmployee();
 
        empTwo.setAge(21);
        empTwo.setDesignation("菜鸟程序员");
        empTwo.setSalary(500);
        empTwo.printEmployee();
    }
}