Java面向对象(三)
Java面向对象(三)
六、面向对象特征之一:封装性
6.1 封装性的引入:
当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受到属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。
但是在实际问题中,我们往往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private)。此时,针对于属性就体现了封装性。
6.2 封装性的体现:
将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值。
注:上面的情况只是 Java 封装性的体现之一,封装性的体现还有:
-
不对外暴露的私有方法;
-
单例模式(将构造器私有化);
-
如果不希望类在包外被使用,则将类设置为缺省
……
6.3 封装性的体现,需要权限修饰符来配合:
-
Java规定的4种权限(从小到大排列):private、缺省、protected 、public
-
4 种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
-
具体的:
4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public
- public类可以在任意地方被访问。
- default类只可以被同一个包内部的类访问。
6.4 总结封装性:
Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
七、类的成员之三:构造器(constructor)
7.1 构造器的作用:
-
创建对象
-
初始化对象的信息
7.2 构造器的特征:
- 它具有与类相同的名称。
- 它不声明返回值类型。(与声明为void不同)。
- 不能被 static、final、synchronized、abstract、native 修饰,不能有 return 语句返回值。
public class PersonTest {
public static void main(String[] args) {
//创建类的对象:new + 构造器
Person p = new Person();
Person p1 = new Person("Tom");
System.out.println(p1.name);
Person p2 = new Person("Jay", 20);
System.out.println(p2.name + " " + p2.age);
}
}
class Person{
//属性
String name;
int age;
//构造器(重载)
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
public Person(String n,int a){
name = n;
age = a;
}
}
7.3 注意:
-
Java语言中,每个类都至少有一个构造器。如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器,默认的空参构造器的权限取决于该类的权限。
-
定义构造器的格式:权限修饰符 类名(形参列表){}。
-
一个类中定义的多个构造器,彼此构成重载。
-
一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器。
-
一个类中,至少会有一个构造器。
-
父类的构造器不可被子类继承。
7.4 属性赋值先后顺序:
-
默认初始化
-
显式初始化
-
构造器中初始化
-
通过“对象.属性“或“对象.方法”的方式赋值
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);
User u1 = new User(2);
System.out.println(u1.age);
u1.setAge(3);
System.out.println(u1.age);
}
}
class User{
String name; // 默认初始化
int age = 1; // 显式初始化
public User(){
}
public User(int a){ // 构造器中初始化
age = a;
}
public void setAge(int a){
age = a;
}
}
/* 输出:
1
2
3
*/
Java 内存分析:
对于 u1 对象的 age 属性:首先是默认初始化为 0 ,然后是显式初始化将 0 改为 1 ,接着是构造器初始化将 1 改为 2 ,最后是通过通过“对象.属性“或“对象.方法”的方式赋值为 3。
八、JavaBean(拓展)
-
JavaBean是一种 Java 语言写成的可重用组件。
-
JavaBean,是指符合如下标准的Java类:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
-
用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以 用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的 JSP 页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用 户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。
-
例子:
public class JavaBean {
private String name; // 属性一般定义为private
private int age;
public JavaBean() {
}
public int getAge() {
return age;
}
public void setAge(int a) {
age = a;
}
public String getName() {
return name;
}
public void setName(String n) {
name = n;
}
}
九、UML类图
-
+ 表示 public 类型, - 表示 private 类型,# 表示protected类型
-
方法的写法:
方法的类型( + 、- ) 方法名(参数名:参数类型):返回值类型
十、this 关键字
10.1 this 关键字的使用:
-
this 可以用来修饰、调用:属性、方法、构造器。
-
它在方法内部使用,即这个方法所属对象的引用;在构造器内部使用,表示该构造器正在初始化的对象。
-
this理解为:当前对象 或 当前正在创建的对象。
10.2 this 修饰属性和方法:
-
在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。
但是,通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
-
在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或方法。
但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
10.3 this 调用构造器
-
可以在类的构造器中使用" this(形参列表)"的方式,调用本类中重载的其他的构造器。
-
构造器中不能通过"this(形参列表)"的方式调用自身构造器。
-
如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了 "this(形参列表)"。
-
"this(形参列表)"必须声明在类的构造器的首行。
-
在类的一个构造器中,最多只能声明一个"this(形参列表)"。
// 一个例子:
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Jerry",20);
System.out.println(p2.getAge());
}
}
class Person{
private String name;
private int age;
public Person(){
String info = "Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)";
System.out.println(info);
}
public Person(String name){
this();
this.name = name;
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);
this.name = name;
//Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
// 省略了this,相当于return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
// 省略了this,相当于return this.age;
}
public void eat(){
System.out.println("人吃饭");
this.study();
}
public void study(){
System.out.println("人学习");
}
}