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;
静态(类)变量在内存中只占唯一内存空间,如下图所示:
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日
}
}
显示结果应为:
2001年1月1日
2001年1月1日
2.成员方法
2.1.一般方法
实例方法: 方法声明中不用 static 修饰, 必须通过对象来调用
类(静态)方法: 方法声明中用 static 修饰, 可以通过类名或对象来调用
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 语句必须是子类构造方法的第一条语句,否则编译器会报错。
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.访问修饰符
- public:一个文件只能有一个 public 类;
- 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 了】
- final 类:不能被继承
- final 方法:不能被重写
- final 变量:不能被修改
- 只读量,且只能被赋值一次,赋值后不能再被修改;
- 被 static final 修饰的变量表常量;
- 赋值方式有两种:直接赋值、构造方法赋值:
final int a = 1;//直接赋值
final int b;//构造方法赋值
{
this.b = 2;
}
5.3.3.abstract
【还是一样,修饰符如其名,是真抽象啊】
- abstract 类:不能被实例化(即不能 new 对象),可以被继承;
- 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 的,即常量
。