跳到主要内容

4. 类与对象、接口

类和对象、接口

1.变量

字段变量:类中的变量
局部变量:方法中的变量

1.1.静态变量与实例变量

  class Circle
{
static double pi; // 类变量
double r; // 实例变量
}
Circle.pi = 3.14;
Circle circle1 = new Circle();
circle1.r = 10.0;
Circle circle2 = new Circle();
circle2.r =100.0;

静态(类)变量在内存中只占唯一内存空间,如下图所示:
3

1.2.传参

示例代码:

Class Date
{
Date(int year, int month, int day)
{
this.year = year;
this.month = month;
this.day = day;
}
void addYear(){
year++;
}
public void display(){
System.out.println(year+"年"+month+"月"+day+"日");
}
public static void main(String[] args){
Date m = new Date(2000,1,1);
Date n = m; // n和m指向同一个对象(地址)
n.addYear(); // n指向的对象的year属性加1,所以m指向的对象的year属性也加1
m.display(); // 2001年1月1日
n.display(); // 2001年1月1日
}
}

显示结果应为:
200111
200111

2.成员方法

2.1.一般方法

信息

实例方法: 方法声明中不用 static 修饰, 必须通过对象来调用
类(静态)方法: 方法声明中用 static 修饰, 可以通过类名或对象来调用
4

class Circle
{
static double pi = 3.14;
double r;
public static void setValue(double givenPi, double givenR) // 静态方法
{
pi = givenPi;
r = givenR; // 错误,静态方法不能访问非静态变量
}
public void setPi(double givenPi) // 实例方法
{
pi = givenPi; // ok, 实例(非静态)方法可以访问静态变量
}

public static void main(String[] args)
{
Circle.setValue(3.14, 10.0); // ok, 通过类名调用静态方法
Circle circle = new Circle();
circle.setValue(3.14, 10.0); // ok, 通过对象调用静态方法

Circle.setPi(3.14); // 错误,不能通过类名调用实例方法
circle.setPi(3.14); // ok, 通过对象调用实例方法
}
}
重载与重写

重载:一个类中可以有同名方法,但是参数列表(即数量或者类型)必须不同,这种方法叫做方法重载 重写:子类中可以有与父类中同名方法,这种方法叫做方法重写

愚见:重载指一个类中的重复加载不同的同名方法;重写指子类重新的父类的同一个方法

2.2.构造方法

用法:用来 new 一个对象:

class Circle
{
double r;
public Circle(double givenR) // 构造方法
{
r = givenR;
}
}
Circle circle = new Circle();
//类名 对象名 = new 构造方法名();

3.关键字

3.1.this

①. 用来区分局部变量和成员变量

class Circle
{
double r;
public Circle(double r) // 构造方法
{
this.r = r; // this.r 表示成员变量 r
}
}
//*****为了方便理解,下面是一样的意思*****//
class Circle
{
double a;
public Circle(double r)
{
a = r;
}
}

② 在构造方法中调用另一个构造方法

class Circle
{
double r;
public Circle(double r) // 一号构造方法
{
this.r = r;
}
public Circle() // 二号构造方法
{
this(10.0); // 调用一号构造方法
}
}

3.2.super

①.访问父类的成员变量

class Son extends Father
{
void main()
{
int a, b, c;
// age为父类的成员变量
a = age;
b = this.age;
c = super.age;
}
}

你会发现,a、b、c 的值都是一样的;此处 super 的目的只是为了更明确的表示访问的是父类的成员变量

②.区别同名的域和方法

void sayHello()
{
super.sayHello(); // 调用父类的 sayHello 方法
System.out.println("Hello,I'm Son");
}

③.调用父类的构造方法

Son(String name, int age, String school)
{
super(name, age); // 在子类的构造方法中调用父类的构造方法
this.school = school;
}
super 语句的位置

super 语句必须是子类构造方法的第一条语句,否则编译器会报错。

4.继承

提示

① Java 中的继承只支持单继承:一个子类只能有一个直接父类,但是一个父类可以有多个子类;
② 没有 extends 的类默认为 java.lang.Object 类的子类;

强制类型转换

class Student extends Person
{
String school;
public static void main()
{
// 1.正常构造
Person zhangsan = new Person("张三", 40);
Student lisi = new Student("李四", 20, "清华大学");

// 2.可以向上转型,new 子类对象赋值给父类变量
Person wangwu = new Student("王五", 18, "北京大学");

// 3.不可以向下转型,new 父类变量赋值给子类变量(空间不够)
Student zhaoliu = new Person("赵六", 30); // 报错

//于是我们要做强制类型转换
//1. 子类可以转变成父类
Person ls = (Person) lisi;

//2. “假父类”可以转变成子类
Student ww = (Student) wangwu;

//3. 父类不能转变成子类
Student zs = (Student) zhangsan; // 报错
}
}

5.访问修饰符

5.1.修饰符

分为:

  • 访问修饰(/控制)符:public、private、protected
  • 其他修饰符:abstract、final、static 等

5.2.访问修饰符

5

提示
  1. public:一个文件只能有一个 public 类;
  2. private:get 和 set 方法针对的变量可以用 private 隐藏起来;

5.3.其他修饰符

5.3.1.static

见上文变量/字段部分。

得到以下结论:
第一层:static 属于整个类而非某一个对象;
第二层:static 方法中不能访问实例变量(如图);
第三层:由二,static 方法中不能使用 this/super

好玩的东西
import Static java.lang.System.*;

System.out.println 就可以写成 out.println 啦~

5.3.2.final

【修饰符如其名,就是 final 了】

  1. final 类:不能被继承
  2. final 方法:不能被重写
  3. final 变量:不能被修改
final 变量
  1. 只读量,且只能被赋值一次,赋值后不能再被修改;
  2. 被 static final 修饰的变量表常量;
  3. 赋值方式有两种:直接赋值、构造方法赋值:
final int a = 1;//直接赋值

final int b;//构造方法赋值
{
this.b = 2;
}
5.3.3.abstract

【还是一样,修饰符如其名,是真抽象啊】

  1. abstract 类:不能被实例化(即不能 new 对象),可以被继承;
  2. abstract 方法:
    只有方法的声明,没有方法体;
    必须被子类重写,不然子类还是个 abstract;
    只要是包含了 abstract 方法的类,就一定得是个 abstract 类。

6.接口

6.1.概念

定义接口:interface(所有方法都是自动 public abstract) 实现接口:implements

信息

与类的单继承不同,接口可以实现多继承
即一个类可以同时实现多个接口

6.2.练习代码

interface Human
{
//接口中不能有构造方法
Human(){}; // 报错

void a();
}
class Shabby implements Human
{
Shabby(){};
public void a()
{
System.out.println("a");
}
}
class interfaceTest
{
public static void main(String[] args)
{
Human zhangsan = new Shabby();//向上转型
Shabby zs = (Shabby) zhangsan;//强制类型转换,向下转型
zs.a();

Shabby lisi = new Human();//error,接口不能实例化&不能向下转型
}
}

6.3.变量

接口中的变量默认是 public static final 的,即常量