一、封装
在编程时,把数据(属性)和有关属性的一些操作(方法)绑定在一起,形成一个不可分开的集合(类),这个过程就是封装(Encapsulation)。
封装时,我们需要隐藏对象的属性和实现细节,仅对外公开接口,并控制在程序中属性的读和写的访问级别。
一般情况下,我们会把所有的属性都私有化,对每个属性提供 getter (读) 和 setter(写) 方法,供外界使用:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Me {
public static void main(String[] args) {
Person person = new Person();
person.setName("Deepspace");
person.setAge(24);
System.out.println(person.getName()); // Deepspace
System.out.println(person.getAge()); // 24
}
}
当然这只是一个很基础的封装,如果想封装出一个好的程序,还得多花很多心思。
1、构造函数
什么是构造函数呢?举个通俗的例子来理解。
宝宝在出生的时候,有的宝宝是出生后再取名字;而有的父母会在宝宝出生之前就取好名字,这样的宝宝一生下来就有名字了。
那在 Java 中,怎么在对象被创建的时候就给对象赋值呢?答案就是通过构造函数对对象进行初始化。还是以给宝宝取名字为例。
出生后再取名字的宝宝:
public class Person {
String name;
int age;
public static void main(String[] args) {
Person person = new Person();
person.name = "陈星星";
person.age = 1;
System.out.println("姓名: " + person.name + ". 年龄: " + person.age); // 姓名: 陈星星. 年龄: 1
}
}
一生下来就有名字的宝宝:
public class Person {
String name;
int age;
Person(String myName, int myAge) {
this.name = myName;
this.age = myAge;
}
public static void main(String[] args) {
Person person = new Person("陈星星", 1);
System.out.println("姓名: " + person.name + ". 年龄: " + person.age); // 姓名: 陈星星. 年龄: 1
}
}
上面的代码中,Person 类中的 Person() 方法就是构造函数,也叫作构造方法或者构造器。
构造函数在类实例化的过程中自动执行,不需要手动调用。构造函数可以在类实例化的过程中做一些初始化的工作。
其实,每个类都有构造函数。如果没有显式地为类定义构造函数,**Java 编译器将会为该类提供一个默认的构造函数。**如:
public class Person {
String name;
int age;
// 编译器会默认加上
Person() {
}
public static void main(String[] args) {
Person person = new Person();
System.out.println("姓名: " + person.name + ". 年龄: " + person.age); // 姓名: null. 年龄: 0
}
}
这一点可以查看编译后的 *.class 文件来验证。
2、构造函数与普通函数的区别
那构造函数和普通函数有什么区别呢?
构造函数的函数名要与类名一样,而普通的函数只要符合标识符的命名规则即可;
一般函数是用于定义对象应该具备的功能,而构造函数定义的是,对象在在创建时,应该具备的一些内容。也就是对象的初始化内容;
构造函数是在对象建立时由 jvm 调用(不能被显示调用),用作对象初始化,不需要手动调用;而一般函数是对象建立后,当对象调用该功能时才会执行,需要手动调用;
构造函数没有返回值类型,也就是说不能有返回值。
3、重载
什么是重载呢?
重载(Overloading):方法名字相同,而参数(参数的个数或者类型)不同,返回类型可以相同也可以不同。
为什么会出现重载?
在大多数程序设计语言中要求为每个方法提供唯一的标识符。如:不能使用 add () 的函数计算整数相加的和之后,又用一个名为 add() 的函数去计算浮点数的和,即每个函数(方法)都要有唯一的名称,但是我们又觉得 add() 这个方法名非常适合,不想更换。
若是 add() 函数可以被重载了,那么就既可以计算整数也可以计算浮点数。所以我们可以这样设计方法为:
int add(int a, int b)
调用 add(10,10)
我们就可以知道是计算两个整数相加。此时,我们又想计算两个浮点数相加,如果想继续使用 add
这个方法名,那就将 add()
方法重载:
double add(double a, double c)
这是重载出现的一个原因。
在 Java 里,构造函数(也说构造器、构造方法)是强制重载方法出现的另一个原因。构造函数的名字由类名决定,那么就只能有一个构造函数。但是,又想使用多种方式用于初始化对象该怎么办呢?那么就只有重载构造函数,使得同名不同参的构造函数同时存在。
4、构造函数的重载
通过重载,在一个类中可以定义多个构造函数,以进行不同的初始化。**比如有的孩子出生前,父母就会为他/她选择好以后要从事的职业,而有的孩子的父母会让孩子长大后自己选择喜欢的职业。看下面的例子:
public class Person {
String name;
int age;
String job;
Person(String myName, int myAge) {
name = myName;
age = myAge;
}
Person(String myName, int myAge, String myJob) {
name = myName;
age = myAge;
job = myJob;
}
public static void main(String[] args) {
Person person1 = new Person("陈星星", 1);
Person person2 = new Person("Deepspace", 1, "software engineer");
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age); // 姓名: 陈星星. 年龄: 1
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age + ". 职业: " + person2.job); // 姓名: 陈星星. 年龄: 1. 职业: software engineer
}
}
4、构造代码块
因为构造函数会重载,那就会有一个问题。比如:如果需要每个小孩出生都要哭的话,那就需要在不同的构造函数中都调用 cry()
这个方法,这就会造成代码重复的问题。怎么解决呢?—— 构造代码块。
public class Person {
String name;
int age;
String job;
// 构造代码块
{
cry(); // 每个 Person 对象创建出来时都会执行这里的代码
}
Person(String myName, int myAge) {
name = myName;
age = myAge;
}
Person(String myName, int myAge, String myJob) {
name = myName;
age = myAge;
job = myJob;
}
public static void main(String[] args) {
Person person1 = new Person("陈星星", 1); // 哇哇哇....
Person person2 = new Person("Deepspace", 1, "software engineer"); // 哇哇哇....
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age); // 姓名: 陈星星. 年龄: 1
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age + ". 职业: " + person2.job); // 姓名: 陈星星. 年龄: 1. 职业: software engineer
}
public void cry() {
System.out.println("哇哇哇....");
}
}
构造代码块的作用就是将所有构造函数中公共的信息进行抽取,用一对花括号包裹起来,每次创建对象时,构造代码块会对所有对象进行统一初始化。
封装篇就分享到这里,给明天找点事情干
在前面的《Java — 面向对象的编程语言》里,介绍了面向对象的三大特征:封装、继承、多态,主要是概念上的讲解,本篇文章将从代码出发,看看 Java 中的封装、继承与多态。
一、封装
在编程时,把数据(属性)和有关属性的一些操作(方法)绑定在一起,形成一个不可分开的集合(类),这个过程就是封装(Encapsulation)。
封装时,我们需要隐藏对象的属性和实现细节,仅对外公开接口,并控制在程序中属性的读和写的访问级别。
一般情况下,我们会把所有的属性都私有化,对每个属性提供 getter (读) 和 setter(写) 方法,供外界使用:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Me {
public static void main(String[] args) {
Person person = new Person();
person.setName("Deepspace");
person.setAge(24);
System.out.println(person.getName()); // Deepspace
System.out.println(person.getAge()); // 24
}
}
当然这只是一个很基础的封装,如果想封装出一个好的程序,还得多花很多心思。
1、构造函数
什么是构造函数呢?举个通俗的例子来理解。
宝宝在出生的时候,有的宝宝是出生后再取名字;而有的父母会在宝宝出生之前就取好名字,这样的宝宝一生下来就有名字了。
那在 Java 中,怎么在对象被创建的时候就给对象赋值呢?答案就是通过构造函数对对象进行初始化。还是以给宝宝取名字为例。
出生后再取名字的宝宝:
public class Person {
String name;
int age;
public static void main(String[] args) {
Person person = new Person();
person.name = "陈星星";
person.age = 1;
System.out.println("姓名: " + person.name + ". 年龄: " + person.age); // 姓名: 陈星星. 年龄: 1
}
}
一生下来就有名字的宝宝:
public class Person {
String name;
int age;
Person(String myName, int myAge) {
this.name = myName;
this.age = myAge;
}
public static void main(String[] args) {
Person person = new Person("陈星星", 1);
System.out.println("姓名: " + person.name + ". 年龄: " + person.age); // 姓名: 陈星星. 年龄: 1
}
}
上面的代码中,Person 类中的 Person() 方法就是构造函数,也叫作构造方法或者构造器。
构造函数在类实例化的过程中自动执行,不需要手动调用。构造函数可以在类实例化的过程中做一些初始化的工作。
其实,每个类都有构造函数。如果没有显式地为类定义构造函数,**Java 编译器将会为该类提供一个默认的构造函数。**如:
public class Person {
String name;
int age;
// 编译器会默认加上
Person() {
}
public static void main(String[] args) {
Person person = new Person();
System.out.println("姓名: " + person.name + ". 年龄: " + person.age); // 姓名: null. 年龄: 0
}
}
这一点可以查看编译后的 *.class 文件来验证。
2、构造函数与普通函数的区别
那构造函数和普通函数有什么区别呢?
构造函数的函数名要与类名一样,而普通的函数只要符合标识符的命名规则即可;
一般函数是用于定义对象应该具备的功能,而构造函数定义的是,对象在在创建时,应该具备的一些内容。也就是对象的初始化内容;
构造函数是在对象建立时由 jvm 调用(不能被显示调用),用作对象初始化,不需要手动调用;而一般函数是对象建立后,当对象调用该功能时才会执行,需要手动调用;
构造函数没有返回值类型,也就是说不能有返回值。
3、重载
什么是重载呢?
重载(Overloading):方法名字相同,而参数(参数的个数或者类型)不同,返回类型可以相同也可以不同。
为什么会出现重载?
在大多数程序设计语言中要求为每个方法提供唯一的标识符。如:不能使用 add () 的函数计算整数相加的和之后,又用一个名为 add() 的函数去计算浮点数的和,即每个函数(方法)都要有唯一的名称,但是我们又觉得 add() 这个方法名非常适合,不想更换。
若是 add() 函数可以被重载了,那么就既可以计算整数也可以计算浮点数。所以我们可以这样设计方法为:
int add(int a, int b)
调用 add(10,10)
我们就可以知道是计算两个整数相加。此时,我们又想计算两个浮点数相加,如果想继续使用 add
这个方法名,那就将 add()
方法重载:
double add(double a, double c)
这是重载出现的一个原因。
在 Java 里,构造函数(也说构造器、构造方法)是强制重载方法出现的另一个原因。构造函数的名字由类名决定,那么就只能有一个构造函数。但是,又想使用多种方式用于初始化对象该怎么办呢?那么就只有重载构造函数,使得同名不同参的构造函数同时存在。
4、构造函数的重载
通过重载,在一个类中可以定义多个构造函数,以进行不同的初始化。**比如有的孩子出生前,父母就会为他/她选择好以后要从事的职业,而有的孩子的父母会让孩子长大后自己选择喜欢的职业。看下面的例子:
public class Person {
String name;
int age;
String job;
Person(String myName, int myAge) {
name = myName;
age = myAge;
}
Person(String myName, int myAge, String myJob) {
name = myName;
age = myAge;
job = myJob;
}
public static void main(String[] args) {
Person person1 = new Person("陈星星", 1);
Person person2 = new Person("Deepspace", 1, "software engineer");
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age); // 姓名: 陈星星. 年龄: 1
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age + ". 职业: " + person2.job); // 姓名: 陈星星. 年龄: 1. 职业: software engineer
}
}
4、构造代码块
因为构造函数会重载,那就会有一个问题。比如:如果需要每个小孩出生都要哭的话,那就需要在不同的构造函数中都调用 cry()
这个方法,这就会造成代码重复的问题。怎么解决呢?—— 构造代码块。
public class Person {
String name;
int age;
String job;
// 构造代码块
{
cry(); // 每个 Person 对象创建出来时都会执行这里的代码
}
Person(String myName, int myAge) {
name = myName;
age = myAge;
}
Person(String myName, int myAge, String myJob) {
name = myName;
age = myAge;
job = myJob;
}
public static void main(String[] args) {
Person person1 = new Person("陈星星", 1); // 哇哇哇....
Person person2 = new Person("Deepspace", 1, "software engineer"); // 哇哇哇....
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age); // 姓名: 陈星星. 年龄: 1
System.out.println("姓名: " + person1.name + ". 年龄: " + person1.age + ". 职业: " + person2.job); // 姓名: 陈星星. 年龄: 1. 职业: software engineer
}
public void cry() {
System.out.println("哇哇哇....");
}
}
构造代码块的作用就是将所有构造函数中公共的信息进行抽取,用一对花括号包裹起来,每次创建对象时,构造代码块会对所有对象进行统一初始化。
封装篇就分享到这里,给明天找点事情干
转载请注明:XAMPP中文组官网 » java封装继承多态实现代码案例