6.类和对象
6.1面向对象概述
面向对象思想是人类最自然的一种思考方式,面向对象设计实质上是对现实世界进行建模。
6.1.1对象
万物皆对象,对象是事物存在的实体
对象被分为静态和动态两个部分,前者被称为属性,即成员变量;后者被称为行为,即方法
6.1.2类
类是同一类事物的统称
对象即符合某个定义所产生出来的实例
在java中,定义格式如下:
权限修饰符 class 类名{...}
6.2面向对象程序设计特点
1.封装性
以类为载体,隐藏实现细节
保证类内数据结构完整性(不能轻易操作数据结构)
2.继承性
关联的一种(关联主要用来描述两个类之间的一般二元关系),可以用树形图表示
子类的实例都是父类的实例,但父类的实例并不是子类的实例
子类继承父类共有的属性和行为,节省重新定义的时间
复用已经定义好的类可以提高系统性能,减少系统出错的几率
3.多态性
不同子类具有相同行为,将子类的对象看作父类的实例对象,此时调用父类即可完成行为
将父类定义为抽象类,在抽象类中给出方法的标准而不给出具体流程
抽象类不能实例化对象,但其子类可以实例化对象,维护时修改父类方法即可
多l态不依赖具体类,由抽象类和接口(更方便)实现
接口,由抽象方法组成的集合,本质上也是一个抽象类
PS:另外还有抽象性,由类和对象体现
6.3权限修饰符
有private(本类可见)、public、protected(不可以修饰类,本包可见)三种
用来控制对类、类的属性、类的方法的访问
不使用权限修饰符时(默认),权限类似protected
类的成员的权限被类的权限所限制
6.4类的成员
1.成员变量
声明如下:
权限 类型 属性名;
类似于C++,类的成员变量可以设置默认值
2.成员方法
声明如下:
权限 返回值类型 方法名(参数列表){
//...
}
this
this关键字表示对本类的对象的引用,常被隐式地用于引用对象的成员变量和方法
举例1:参数赋值
public Human(int tall,int weight,String sex,int age){
this.tall=tall;
this.weight=weight;
this.sex=sex;
this.age=age;
}
举例2:返回类引用
public Human getHuman() {
return this;
}
6.5构造方法
类在实例化一个对象时会自动调用
构造方法的名称与类名相同,没有返回值(区别void)
类中没有定义构造方法时,编译器会自动生成一个不带参数构造方法
ps:声明了带参数的构造方法,编译器不会自动生成不带参构造方法,试图调用无参构造方法时,会产生错误
构造方法语法格式:
public 类名(){
...//构造方法体
}
举例1:this实现构造方法重载
public Human() {
this(30, 167, 50, "female");
// 通过this调用有参构造方法
// 只可以在无参数构造方法第一句调用this关键字
}
public Human(int age, int weight, int height, String sex) {
this.age = age;
this.height = height;
this.sex = sex;
this.weight = weight;
}
举例2:当构造方法私有,其他类无法用new实例化
public class Book {
//私有构造函数
private Book() { }
//静态方法,返回本类实例
static public Book Borrow(){
return new Book();
}
}
此时,为了创建新的对象,应在其他类中调用返回本类实例的静态方法:
Book book=Book.Borrow();
ps:需要生成新的对象,调用返回值为 new 类名 的静态函数,这是编程设计中的单例模式
6.6 静态变量、常量、方法
被声明为static的变量、常量和方法被称为静态成员。
静态成员属于类所有,被修饰符所约束,通过”类名.静态成员名”访问(区别非静态成员)
静态区在整个程序运行结束后才会释放,故静态成员生命周期是整个程序生命周期
1.静态变量
在普通成员变量前加上static即是静态变量,举例如下:
static public int tall;
2.静态常量
在静态变量前加上final表示常量,注意定义时需要初始化:
final static int tall=167;
PS:无论变量还是常量,只要在方法体内,都不可以定义为静态的
3.静态方法
在普通方法前加上static
常在不想或者不需要创建对象,需要使用方法时调用类的静态方法
System.out.print()即是一个静态方法,没有创建System对象即实现了输出功能
注意事项:
(1)静态方法中不可以使用this关键字
(2)静态方法不可以直接调用非静态方法
(3)所以在main()函数中,调用非静态方法需要通过对象调用,否则要定义为静态方法)
4.静态代码块
类中用static定义的一个区域,将在类的初始化操作,将在类定义时执行
非静态代码块,类中用”{ }”定义的一个区域,将在每次类new一个实例时执行,并且在构造函数之前运行
6.5类的主方法
public static void main(String[] args) {
}
主方法是类的入口,定义了程序从何处运行
由于主方法静态,主方法调用的方法也必须是静态方法,否则要通过实例化的对象调用
主方法的形参是命令行参数,arg[0]~arg[n-1]表示程序的第1个到第n个参数,可以通过args.length获取参数个数
命令行参数可以手动输入
6.6对象
6.6.1对象创建
通过new操作符创建对象,每一次创建都会匹配调用构造函数
语法如下:
Human Bob=new Human();
6.6.2对象的访问
访问对象的属性和行为时,通过”类名.成员”的形式访问
6.6.3对象的引用
Human Bob=new Human();
Human 类名
Bob 对象的引用
new Human() 对象的实体
引用存放一个对象的内存地址,严格意义上来说,是Bob包含Human对象的一个引用,所以下方两种方式均可调用showHuman()方法
Human Bob=new Human();
System.out.println(Bob.showHuman());
System.out.println(new Human().showHuman());
6.6.4对象的比较
(1)直接将两个对象用”==”比较,将比较两个对象地址是否一致
(2)一个对象调用equals()比较另外一个对象,将比较两个对象引用所指的内容是否相等
6.6.5对象的销毁
(1)通过new操作符获取的对象,其生命周期结束时,其内存地址将会被自动回收。
(2)对于不是new出来的对象,Object类中有一个finalize()方法,被声明为protected,用户可以在自己类中定义这个方法。当用户定义了这个方法,垃圾回收时会首先调用该方法,下一次垃圾回收动作发生时,将真正回收被对象占用的内存。
(3)垃圾回收时间不定,不受人为控制,可以通过System.gc()方法强制启动垃圾回收器。
PS:当Java虚拟机内存耗尽,将不会执行垃圾回收。