大部分笔记来自:微学苑

类定义和实例化

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

  • 局部变量:在方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
  • 成员变量:成员变量是定义在类中、方法体之外的变量。这种变量在创建对象的时候实例化(分配内存)。成员变量可以被类中的方法和特定类的语句访问。
  • 类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。static 也是修饰符的一种,将在下节讲解。

构造方法

在类实例化的过程中自动执行的方法叫做构造方法,它不需要你手动调用。构造方法可以在类实例化的过程中做一些初始化的工作。

构造方法的名称必须与类的名称相同,并且没有返回值。

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

说明:

  • 构造方法不能被显示调用
  • 构造方法不能有返回值,因为没有变量来接收返回值。

创建对象

Dog myDog;  // 声明一个对象
myDog = new Dog("花花", 3);  // 实例化

也可以,

Dog myDog = new Dog("花花", 3);

访问修饰符(访问控制符)

名称 作用
public 共有的,对所有类可见。
protected 受保护的,对同一包内的类和所有子类可见。
private 私有的,在同一类内可见。
默认的 在同一包内可见。默认不使用任何修饰符。

Java程序的main() 方法必须设置成公有的,否则,Java解释器将不能运行该类。

protected

public class Dog{
   
    protected void bark() {
        System.out.println("汪汪,不要过来");
    }
}
class Teddy extends Dog{
     // 泰迪
    void bark() {
        System.out.println("汪汪,我好怕,不要跟着我");
    }
}

如果把bark()方法声明为private,那么除了Dog之外的类将不能访问该方法。如果把bark()声明为public,那么所有的类都能够访问该方法。如果我们只想让该方法对其所在类的子类可见,则将该方法声明为protected。

private

public class Dog{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

例子中,Dog类中的name、age变量为私有变量,所以其他类不能直接得到和设置该变量的值。为了使其他类能够操作该变量,定义了两对public方法,getName()/setName() 和 getAge()/setAge(),它们用来获取和设置私有变量的值。

this 是Java中的一个关键字,本章会讲到,你可以点击 Java this关键字详解 预览。

在类中定义访问私有变量的方法,习惯上是这样命名的:在变量名称前面加“get”或“set”,并将变量的首字母大写。例如,获取私有变量 name 的方法为 getName(),设置 name 的方法为 setName()。这些方法经常使用,也有了特定的称呼,称为 Getter 和 Setter 方法。

继承

请注意以下方法继承(不了解继承概念的读者可以跳过这里,或者点击 Java继承和多态 预览)的规则:

  • 父类中声明为public的方法在子类中也必须为public。
  • 父类中声明为protected的方法在子类中要么声明为protected,要么声明为public。不能声明为private。
  • 父类中默认修饰符声明的方法,能够在子类中声明为private。
  • 父类中声明为private的方法,不能够被继承。

变量的作用域

在Java中,变量的作用域分为四个级别:类级、对象实例级、方法级、块级。

类级变量又称全局级变量静态变量,需要使用static关键字修饰,你可以与 C/C++ 中的 static 变量对比学习。类级变量在类定义后就已经存在,占用内存空间,可以通过类名来访问,不需要实例化。

对象实例级变量就是成员变量,实例化后才会分配内存空间,才能访问。

方法级变量就是在方法内部定义的变量,就是局部变量

块级变量就是定义在一个块内部的变量,变量的生存周期就是这个块,出了这个块就消失了,比如 if、for 语句的块。块是指由大括号包围的代码

public class Demo{
    public static String name = "微学苑";  // 类级变量
    public int i; // 对象实例级变量
    // 属性块,在类初始化属性时候运行
    {
        int j = 2;// 块级变量
    }
    public void test1() {
        int j = 3;  // 方法级变量
        if(j == 3) {
            int k = 5;  // 块级变量
        }
        // 这里不能访问块级变量,块级变量只能在块内部访问
        System.out.println("name=" + name + ", i=" + i + ", j=" + j);
    }
    public static void main(String[] args) {
        // 不创建对象,直接通过类名访问类级变量
        System.out.println(Demo.name);

        // 创建对象并访问它的方法
        Demo t = new Demo();
        t.test1();
    }
}

this关键字

this 关键字用来表示当前对象本身,或当前类的一个实例,通过 this 可以调用本对象的所有方法和属性。

注意:this 只有在类实例化后才有意义。

Java 默认将所有成员变量和成员方法与 this 关联在一起,因此使用 this 在某些情况下是多余的。

方法重载

在Java中,同一个类中的多个方法可以有相同的名字,只要它们的参数列表不同就可以,这被称为方法重载(method overloading)。

参数列表又叫参数签名,包括参数的类型、参数的个数和参数的顺序,只要有一个不同就叫做参数列表不同。

重载是面向对象的一个基本特性。

说明:

  • 参数列表不同包括:个数不同、类型不同和顺序不同。

  • 仅仅参数变量名称不同是不可以的。

  • 跟成员方法一样,构造方法也可以重载。

  • 声明为final的方法不能被重载。

  • 声明为static的方法不能被重载,但是能够被再次声明。

包装类、拆箱和装箱

虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程

为解决此类问题 ,Java为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes),也有教材称为外覆类或数据类型类。

基本类型和对应的包装类可以相互装换:
由基本类型向对应的包装类转换称为装箱,例如把 int 包装成 Integer 类的对象;
包装类向对应的基本类型转换称为拆箱,例如把 Integer 类的对象重新简化为 int。

这部分详见http://www.weixueyuan.net/view/5990.html

自动拆箱和装箱

上面的例子都需要手动实例化一个包装类,称为手动拆箱装箱。Java 1.5(5.0) 之前必须手动拆箱装箱。

Java 1.5 之后可以自动拆箱装箱,也就是在进行基本数据类型和对应的包装类转换时,系统将自动进行,这将大大方便程序员的代码书写。例如:

public class Demo {
    public static void main(String[] args) {
        int m = 500;
        Integer obj = m;  // 自动装箱
        int n = obj;  // 自动拆箱
        System.out.println("n = " + n);

        Integer obj1 = 500;
        System.out.println("obj 等价于 obj1?" + obj.equals(obj1));
    }
}

运行结果:
n = 500
obj 等价于 obj1?true

自动拆箱装箱是常用的一个功能,读者需要重点掌握。

如何实现包

必须将 package 语句放在所有语句的前面,例如:

package p1.p2;
public class Test {
    public Test(){
        System.out.println("我是Test类的构造方法");
    }
}

包的调用

实际编程中,没有必要把要引入的类写的那么详细,可以直接引入特定包中所有的类,例如 import java.util.*;。