黑马程序员_JavaSE基础知识总结五:类与对象的区分及封装特性

来源:互联网 发布:mysql 函数 编辑:程序博客网 时间:2024/05/17 02:12

------ android培训java培训、期待与您交流! ----------


“万物皆对象”是Java编程的核心思想,Java语言将对象视为奇特的变量,它可以存储数据,除此之外,你还可以要求它在自身上执行操作。用木匠打一个比方,一个“面向对象的”木匠始终关注的是所制作的椅子,第二位才是所使用的工具,面向对象编程思想的优势在于:①将复杂的事情简单化;②面向对象将以前的过程中的执行者,变成了指挥者;③面向对象这种思想是符合现在人们思考习惯的一种思想。

 

一、类与对象的区分

类(class)是对具有共性事物的抽象描述,是构造对象的模板或蓝图,是在概念上的一个定义,类也是Java程序的基本单位,那么如何发现类呢?

通常根据名词(概念)来发现类,如在成绩管理系统中:学生、班级、课程、成绩等。

类    对象

学生—张三

班级—622

课程—J2SE

成绩—张三成绩

以上“学生”、“班级”、“课程”、“成绩”等是对象,他们是抽象出来的,称为类;而“张三”、“622”、“J2SE”和“张三的成绩”他们是具体存在的,称为对象,也叫实例(istance),也就是说一个类的具体化(实例化),就是对象或实例。

类与对象关系总结如下:①类=属性+方法,属性来源于类的状态,而方法来源于动作;②每个对象都拥有其类型,每个对象都是某个类的一个实例;③面向对象设计语言使程序员不会受限于任何特定类型的问题,程序可以通过添加新类型的对象使自身适用于某个问题。

 

二、类的定义

Java中定义类的具体格式:

修饰限定符  class  类名  extends  父对象名称  implements  接口名称  { 

类体:属性和方法组成

}


public class Student {//学号int id;//姓名String name;//性别boolean sex;//地址String address;//年龄int age;} 

以上属性称为成员变量,成员变量和局部变量的区别如下:

①成员变量直接定义在类中,局部变量定义在方法中,参数上,语句中;②成员变量在这个类中有效,局部变量只在自己所属的大括号内有效,大括号结束,局部变量失去作用域;③成员变量存在于堆内存中,随着对象的产生而存在、消失而消失,局部变量存在于栈内存中,随着所属区域的运行而存在,结束而释放;④局部变量使用前必须初始化,否则程序编译时会报错,而成员变量会默认初始化,初始化的值名为该类型的默认值。具体的默认值如下:

类型

默认值

byte

0

short

0

int

0

long

0L

char

‘\u0000’

float

0.0f

double

0.0d

boolean

false

引用类型

null


三、对象的创建和引用

Java中使用new 关键字来创建对象,使用引用(reference)来操作对象。

public class OOTest01 {public static void main(String[] args) {//创建一个对象Student zhangsan = new Student();System.out.println("id=" + zhangsan.id);System.out.println("name=" + zhangsan.name);System.out.println("sex=" + zhangsan.sex);System.out.println("address=" + zhangsan.address);System.out.println("age=" + zhangsan.age);}}
class Student {//学号int id;//姓名String name;//性别boolean sex;//地址String address;//年龄int age;}

对成员变量进行赋值

public class OOTest02 {public static void main(String[] args) {//创建一个对象Student zhangsan = new Student();zhangsan.id = 1001;zhangsan.name = "张三";zhangsan.sex = true;zhangsan.address = "北京";zhangsan.age = 20;System.out.println("id=" + zhangsan.id);System.out.println("name=" + zhangsan.name);System.out.println("sex=" + zhangsan.sex);System.out.println("address=" + zhangsan.address);System.out.println("age=" + zhangsan.age);}}class Student {//学号int id;//姓名String name;//性别boolean sex;//地址String address;//年龄int age;}

一个类可以创建N 个对象,成员变量只属于当前的对象(只属于对象,不属于类),只有通过对象才可以访问成员变量,通过类不能直接访问成员变量



四、匿名对象的特点

匿名对象可以通俗理解为没有名字的对象,匿名对象使用场景:

1当对方法只进行一次调用的时候,可以使用匿名对象

2当对象对成员进行多次调用时,不能使用匿名对象。必须给对象起名字。

 

匿名对象调用方法时调用完毕就成了垃圾,等待垃圾回收器回收。

 

为了进一步理解匿名对象的特点,且看以下两道题:

题1:class Test {int num = 3;public static void main(String[] args) {Test t = new Test();t.num = 5;method(t);System.out.println(t.num);}public static void method(Test t){t.num = 6;}}</span>
题2:class Test {int num = 3;public static void main(String[] args) {Test t = new Test();t.num = 5;method(new Test());System.out.println(t.num);}public static void method(Test t){t.num = 6;}}</span>

题1打印输出的是6,题2打印输出的是5,method(new Test())是创建了一个匿名对象,与Test t 在堆内存中的地址是不同的,因此System.out.println(t.num);语句仍然输出的是5。


 

五、面向对象的封装性

以上程序存在缺点,年龄可以赋值为负数,怎么控制不能赋值为负数?

控制对年龄的修改,年龄只能为大于等于并且小于等于120 的值

public class OOTest03 {public static void main(String[] args) {//创建一个对象Student zhangsan = new Student();/*zhangsan.id = 1001;zhangsan.name = "张三";zhangsan.sex = true;zhangsan.address = "北京";zhangsan.age = 20;*/zhangsan.setId(1001);zhangsan.setName("张三");zhangsan.setSex(true);zhangsan.setAddress("北京");zhangsan.setAge(-20);System.out.println("id=" + zhangsan.id);System.out.println("name=" + zhangsan.name);System.out.println("sex=" + zhangsan.sex);System.out.println("address=" + zhangsan.address);System.out.println("age=" + zhangsan.age);}}class Student {//学号int id;//姓名String name;//性别boolean sex;//地址String address;//年龄int age;//设置学号public void setId(int studentId) {id = studentId;}//读取学号public int getId() {return id;}public void setName(String studentName) {name = studentName;}public String getName() {return name;}public void setSex(boolean studentSex) {sex = studentSex;}public boolean getSex() {return sex;}public void setAddress(String studentAddress) {address = studentAddress;}public String getAddress() {return address;}public void setAge(int studentAge) {if (studentAge >=0 && studentAge <=120) {age = studentAge;}}public int getAge() {return age;}}

从上面的示例,采用方法可以控制赋值的过程,加入了对年龄的检查,避免了直接操纵student属性,这就是封装,封装其实就是封装属性,让外界知道这个类的状态越少越好。以上仍然不完善,采用属性仍然可以赋值,如果屏蔽掉属性的赋值,只采用方法赋值,如下:

public class OOTest04 {public static void main(String[] args) {//创建一个对象Student zhangsan = new Student();zhangsan.id = 1001;zhangsan.name = "张三";zhangsan.sex = true;zhangsan.address = "北京";zhangsan.age = 20;/*zhangsan.setId(1001);zhangsan.setName("张三");zhangsan.setSex(true);zhangsan.setAddress("北京");zhangsan.setAge(20);*//*System.out.println("id=" + zhangsan.id);System.out.println("name=" + zhangsan.name);System.out.println("sex=" + zhangsan.sex);System.out.println("address=" + zhangsan.address);System.out.println("age=" + zhangsan.age);*/System.out.println("id=" + zhangsan.getId());System.out.println("name=" + zhangsan.getName());System.out.println("sex=" + zhangsan.getSex());System.out.println("address=" + zhangsan.getAddress());System.out.println("age=" + zhangsan.getAge());}}class Student {//学号private int id;//姓名private String name;//性别private boolean sex;//地址private String address;//年龄private int age;//设置学号public void setId(int studentId) {id = studentId;}//读取学号public int getId() {return id;}public void setName(String studentName) {name = studentName;}public String getName() {return name;}public void setSex(boolean studentSex) {sex = studentSex;}public boolean getSex() {return sex;}public void setAddress(String studentAddress) {address = studentAddress;}public String getAddress() {return address;}public void setAge(int studentAge) {if (studentAge >=0 && studentAge <=120) {age = studentAge;}}public int getAge() {return age;}}

以上采用private 来声明成员变量,那么此时的成员变量只属于Student,外界无法访问,这样就封装了我们的属性,那么属性只能通过方法访问,通过方法我们就可以控制对内部状态的读取权利。

总结,Java采用封装性的好处主要如下:①将变化隔离;②便于使用;③提高重用性;④增加安全性

 


六、构造函数(构造方法,构造器,Constructor)

构造方法主要用来创建类的实例化对象,可以完成创建实例化对象的初始化工作,声明格式:

构造方法修饰词列表   类名   (方法参数列表)

构造方法修饰词列表:public、proteced、private

类的构造方法和普通方法一样可以进行重载

构造方法具有的特点:

构造方法名称必须与类名一致

构造方法不具有任何返回值类型,即没有返回值,关键字void 也不能加入,加入后就不是构造方法了,就成了普通的方法了

任何类都有构造方法,如果没有显示的定义,则系统会为该类定义一个默认的构造器,这个构造器不含任何参数,如果显示的定义了构造器,系统就不会创建默认的不含参数的构造器了。

 

1.默认构造方法(无参构造方法)

public class ConstructorTest01 {public static void main(String[] args) {// 创建一个对象Student zhangsan = new Student();zhangsan.setId(1001);zhangsan.setName("张三");zhangsan.setSex(true);zhangsan.setAddress("北京");zhangsan.setAge(20);System.out.println("id=" + zhangsan.getId());System.out.println("name=" + zhangsan.getName());System.out.println("sex=" + zhangsan.getSex());System.out.println("address=" + zhangsan.getAddress());System.out.println("age=" + zhangsan.getAge());}}class Student {// 学号private int id;// 姓名private String name;// 性别private boolean sex;// 地址private String address;// 年龄private int age;// 默认构造方法public Student() {// 在创建对象的时候会执行该构造方法// 在创建对象的时候,如果需要做些事情,可以放在构造方法中System.out.println("----------Student-------------");}// 设置学号public void setId(int studentId) {id = studentId;}// 读取学号public int getId() {return id;}public void setName(String studentName) {name = studentName;}public String getName() {return name;}public void setSex(boolean studentSex) {sex = studentSex;}public boolean getSex() {return sex;}public void setAddress(String studentAddress) {address = studentAddress;}public String getAddress() {return address;}public void setAge(int studentAge) {if (studentAge >= 0 && studentAge <= 120) {age = studentAge;}}public int getAge() {return age;}}

2.带参数的构造方法


public class ConstructorTest02 {public static void main(String[] args) {// 调用带参数的构造方法对成员变量进行赋值Student zhangsan = new Student(1001, "张三", true, "北京", 20);System.out.println("id=" + zhangsan.getId());System.out.println("name=" + zhangsan.getName());System.out.println("sex=" + zhangsan.getSex());System.out.println("address=" + zhangsan.getAddress());System.out.println("age=" + zhangsan.getAge());}}class Student {// 学号private int id;// 姓名private String name;// 性别private boolean sex;// 地址private String address;// 年龄private int age;public Student(int studentId, String studentName, boolean studentSex,String studentAddress, int studentAge) {id = studentId;name = studentName;sex = studentSex;address = studentAddress;age = studentAge;}// 设置学号public void setId(int studentId) {id = studentId;}// 读取学号public int getId() {return id;}public void setName(String studentName) {name = studentName;}public String getName() {return name;}public void setSex(boolean studentSex) {sex = studentSex;}public boolean getSex() {return sex;}public void setAddress(String studentAddress) {address = studentAddress;}public String getAddress() {return address;}public void setAge(int studentAge) {if (studentAge >= 0 && studentAge <= 120) {age = studentAge;}}public int getAge() {return age;}}

需要注意的是,手动建立的构造方法,将会把默认的构造方法覆盖掉

3.构造代码块和构造函数有什么区别?

构造代码块:是给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块。只要对象一建立。就会调用这个代码块。

构造函数:是给与之对应的对象进行初始化。它具有针对性。

 

 










0 0
原创粉丝点击