6.1 面向对象概述
在程序开发初期,人们使用结构化开发语言。随着软件的规模越来越庞大,结构化语言的弊端也逐渐暴露出来,开发周期越来越长,产品的质量也不尽人意。这时人们开始将另一种开发思想引入程序中,即面向对象的开发思想。面向对象思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,通过了解这些对象具有哪些相应的属性以及展示这些对象行为,以解决这些对象面临的一些实际问题。在程序开发中引入面向对象设计的概念,其实质上就是对现实世界中的对象进行建模操作。
6.1.1 对象
现实生活中,随处可见的一种事物就是对象。对象是事物存在的实体,如人、书桌、计算机、高楼大厦等。人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的。通常都会将对象划分为两个部分,即静态部分与动态部分。顾名思义,静态部分就是不能动的部分,这个部分被称为“属性”,任何对象都会具备其自身属性,如一个人,其属性包含高矮、胖瘦、性别、年龄等。动态部分即对象可执行的动作,这部分称为“行为”,也是一个值得探讨的部分,同样对于一个人,其可以哭泣、微笑、说话、行走,这些都是这个人具备的行为。人类通过探讨对象的属性和观察对象的行为来了解对象。
在计算机的世界中,面向对象程序设计的思想要以对象来思考问题,首先要将现实世界的实体抽象为对象,然后考虑这个对象具备的属性和行为。
6.1.2 类
不能将一个事物描述成一类事物,如一只鸟不能称为鸟类。但如果要给某一事物一个统称,就需要用到类这个概念。
类及时同一类事物的统称,如果将现实世界中的一个事物抽象成对象,类就是这类对象等等统称,如鸟类、家禽类、人类等。类是构造对象时所依赖的规范,如一只鸟有一对翅膀,它可以用这对翅膀飞行,而基本上所有的鸟都具有“有翅膀”这个特性和飞行的技能,这样具有相同特性和行为的一类事物就称为类,类的思想就是这样产生的。
类是封装对象的属性和行为的载体,反过来说,具有相同属性和行为的一类实体被称为类。
在JAVA语言中,类对象的行为是以方法的形式定义的,对象的属性是以成员变量的形式定义的,所以类包括对象的属性和方法。
6.1.3 封装
面向对象程序设计具有一下特点:封装性、继承性和多态性。
封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装思想。例如,用户使用计算机时,只需要使用手指敲击键盘就可以实现一些功能,无须知道计算机内部是如何工作原理,但在使用计算机时也并不完全依赖于计算机工作原理等细节。
采用封装的思想保证了类内部数据结构的完整性,使用类的用户不能轻易地直接操作类的数据结构,只能执行类允许公开的数据。这样就避免了外部操作对内部数据的影响,提高了程序的可维护性。
6.1.4 继承
类与类之间同样具有关系,这种关系被称为关联。关联主要描述两个类之间的一般二元关系。例如,一个百货公司类与销售员类就是一个关联,学生类与教师类就是一个关联。两个类之间的关系有很多种,继承是关联的一种。
从上图中可以看出,继承关系可以使用树形关系来表达,父类与子类存在一种层次关系。一个类处于继承体系中,它既可以是其他类型的父类,为其他类提供属性和行为,也可以是其他类的子类,继承父类的属性和方法,如三角形类既是图形类的子类也是等边三角形的父类。
6.1.5多态
6.2 类
6.2.1 成员变量
在Java中,对象的属性也称为成员变量,成员变量可以是任意类型,整个类中均是成员变量作用范围。
例6.1为书添加书名属性
public class Book { //类
private String name; //String类型的成员变量
public String getName() { //name的Getter方法
return name;
}
public void setName(String name) { //name的Setter方法
this.name =name; //将参数值赋予类中的成员变量
}
}
在上面可以看到,在Java语言中需要使用class关键字来定义类,Book是类的名称。同时在Book类中定义了一个成员变量,成员变量的类型为String类型。其实成员变量就是普通变量,可以为它设置初始值,也可以不设置初始值,如果没有初始值,则会有默认值。
6.2.2 成员方法
在Java语言中,使用成员方法对应于类对象的行为。一个·成员方法可以有参数,这个参数可以是对象,也可以是基本数据类型的变量,同时成员方法有返回值和不返回任何值的选择,如果方法需要返回值,可以在方法体中使用return关键字,使用这个关键字后,方法的执行将被终止。
6.2.3 仅限修饰符
6.2.4 局部变量
局部变量是在方法被执行是创建,在方法执行结束时销毁。局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译器错误。
例6.2交换两个整数值
public class ChangDemo {
public static int[] exchange(int[] arr) {
int tmp = arr[0]; //创建局部变量tmp,保存数组第一个元素的值
arr[0] = arr[1]; //第二个元素值赋给第一个元素
arr[1] = tmp; //第二个元素值改为tmp
return arr;
}
public static void main(String[] args) {
int arr[] = {17,29};
System.out.println("第一个值="+arr[0]+",第二个值="+arr[1]);
arr = exchange(arr);
System.out.println("第一个值="+arr[0]+",第二个值="+arr[1]);
}
}
结果为:
6.2.5 局部变量的有效范围
可以将局部变量的有效范围称为变量的作用域,局部变量的有效范围从该变量的声明开始到该变量的结束为止。
在相互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量。
但是在相互嵌套的区域中不可以这样声明,如果将局部变量id在方法体的for循环中再次定义,编译器将会报错。
6.3类的构造方法
例6.3“构造”鸡蛋灌饼
public class EggCake {
int eggCount; //鸡蛋灌饼里蛋的个数
public EggCake(int eggCount) { //参数为鸡蛋灌饼里蛋的个数的构造方法
this.eggCount = eggCount; //参数eggCount的值付给属性eggCount
}
public EggCake() { //无参数构造方法,默认给饼加一个蛋
this(1); //调用参数为鸡蛋灌饼里蛋的个数的构造方法,并设置鸡蛋灌饼里蛋的个数为1
}
public static void main(String[] args) {
EggCake cake1 = new EggCake();
System.out.println("顾客不要求加蛋的数量,饼里会有"+cake1.eggCount+"个蛋。");
EggCake cake2 = new EggCake(2);
System.out.println("顾客要求加蛋的数量,饼里会有"+cake2.eggCount+"个蛋。");
}
}
结果为:
6.4静态变量和静态方法
静态就是static,可以有静态常量、静态变量、静态方法和多个语句静态
静态是这个类的专属,只有这个类可以用,就是这个文件可以用,只要它们在一个文件里就行
例6.4
public class StaticDemo {
static double PI = 3.1415; //在类中定义静态变量
public static void method() { //在类中定义静态方法
System.out.println("这是静态方法");
}
public static void main(String[]args) {
System.out.println(StaticDemo.PI); //调用静态变量
StaticDemo.method(); //调用静态方法
}
}
结果为:
例6.5
public class Cust { //顾客类
static int count = 0; //共享的属性:人数
String name; //名称属性
public Cust(String name) {
this.name = name; //记录名称
count++; //人数递增
}
public static void main(String[]args) {
Cust c1 = new Cust("tom");
System.out.println("我是第"+Cust.count+"名客户,我叫"+c1.name);
Cust c2 = new Cust("张三");
System.out.println("我是第"+Cust.count+"名客户,我叫"+c2.name);
Cust c3 = new Cust("狗蛋儿");
System.out.println("我是第"+Cust.count+"名客户,我叫"+c3.name);
}
}
结果为:
6.5 类的主方法
(String [] args)有什么用,怎么用
package b;
public class s {
public static void main(String [] args) {//主方法
for(int i=0;i<args.length;i++) {//根据参数个数做循环操作
System.out.println(args[i]);//打印结果
}
}
}
在代码运行前要先设置参数,右击界面
点击,然后以下操作
然后输入,用换行隔开
例6.6
package liudanyuan;
public class lei6_6 {
public static void main(String[] args) { //定义主方法
for(int i = 0;i<args.length;i++) { //根据参数个数做循环操作
System.out.println(args[i]); //循环打印参数内容
}
}
}
结果为:
6.6 对象
test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间
例6.7
public class People {
String name;
int age;
String sex;
public People() {
}
public People(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public static void main(String[]args) {
People p1 = new People("tom",23,"男");
People p2 = new People("lily",19,"女");
}
}
例6.8
public class Dog { //狗
String name; //名字
String Color; //颜色
String vioce; //声音
public Dog(String name,String color,String vioce) {
this.name = name;
this.Color = color;
this.vioce = vioce;
}
public void call() { //叫
System.out.println(vioce);
}
public static void main(String[]args) {
Dog d1 = new Dog("毛毛","白色","汪汪汪");
System.out.print(d1.name+"的颜色是"+d1.Color); //访问对象的属性
System.out.print(",叫起来的声音:");
d1.call(); //访问对象的行为
Dog d2 = new Dog("灰灰","灰色","嗷呜~");
System.out.print(d2.name+"的颜色是"+d2.Color);
System.out.print(",叫起来的声音:");
d2.call();
}
}
结果为:
6.6.3对象的引用
真正的操作标识符实质上是一个引用,引用的语法
类名 对象的引用变量
b d1 =new b();
b是类名,d1是引用名,new b对象的实体;
6.6.4 对象的销毁
为什么要销毁对象
每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址需要被回收
垃圾回收器
在其他语言中,需要用户手动回收废弃的对象,JAVA拥有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收器会自动回收无用却占用内存的资源
怎么判断对象会被JAVA虚拟机视为垃圾?主要包括两种情况
对象引用超过其作用范围,这个对象将被视为垃圾
将对象赋值为null
不足
虽然JAVA的垃圾回收机制已经很完善,但垃圾回收只能回收那些由new操作符创建的对象
某些对象不是通过new创造并获得存储空间的这些对象是无法被垃圾回收机制所识别
finalize()
那么JAVA提供了一个finalize方法
这个方法是object类方法,他被声明为protected,用户可以在自己的类中定义这个方法,定义了这个方法后,垃圾回收时会首先调用该方法
system.gc()
由于垃圾回收不受人为控制,具体的执行时间也不能明确的确定,所以finalize()方法也就无法执行,因此JAVA又提供了system.gc()方法来强制启动垃圾回收器,会主动告知垃圾回收器来清理垃圾