一、初识面向对象
1.1 什么是面向对象
面向对象是解决问题的一种思想,主要依靠对象之间的交互来完成一件事情。
1.2 面向对象与面向过程
- 一般人买手机过程
一般人买手机,其过程都是亲力亲为,这就是面向过程。
- 董事长买手机过程
这个过程中的对象是:董事长、秘书、手机;董事长只需要给秘书说买手机,至于怎么买手机的这个过程,是由秘书来操作的。完成这件事的时候,你只需要与对象之间进行交互,那么这件事情就可以完成,这就是面向过程。
二、类的定义和使用
2.1 类的定义
类是对一个实体对象进行描述的,我们可以自定义类。
- 类的定义格式
class Dog{
//1、字段 / 属性 【成员变量】
//2、行为 / 方法 【成员方法】
}
例 定义一个类:
class Dog{
public String name;
public int age;
public String color;
public void wag(){
System.out.println(name + " 摇尾巴");
}
public void bark(){
System.out.println(name + " 犬吠");
}
}
2.2 类的实例化
什么是实例化:定义了一个类,就相当于在计算机中定义了一中新的类型,类似于Java中自带的 int、byte,用类类型创建对象的过程,称为类的实例化。
在Java中采用new关键字,配合类名来实例化对象。
例:
public class Test1 {
public static void main(String[] args) {
Dog dog = new Dog();
System.out.println(dog.age);
System.out.println(dog.color);
System.out.println(dog.name);
dog.bark();
dog.wag();
}
}
实例化对象未进行初始化时,将其打印,得到结果不会报错,是因为这些变量是成员变量,成员变量未初始化时有默认值,而局部变量不初始化就会报错。
- 引用数据类型—》null
- 基本数据类型—》0
- boolean:false
- char:'\u0000'
-
一个类可以实例化多个对象
class Dog{
//成员变量
public String name;
public int age;
public String color;
public void wag(){
System.out.println(name + " 摇尾巴");
}
public void bark(){
System.out.println(name + " 犬吠");
}
}
public class Test1 {
public static void main(String[] args) {
Dog dog1 = new Dog();
Dog dog2 = new Dog();
dog1.name = "阿黄";
dog2.name = "阿白";
dog1.bark();
dog2.bark();
}
}
2.2 类和对象的说明
- 类是一个模型一样的东西,用来对一个实体的描述,限定了实体有哪些成员。
- 类是一个自定义类型,可以定义很多个变量。
- 一个类可以实例化多个对象,实例化出的对象占用实际的物理空间,储存 类成员变量,就像是用图纸来建房子,类就是图纸,房子就是对象。
三、this引用
例如一个日期的类:
public class Data {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
year = year;
month = month;
day = day;
}
public void printData(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Data day1 = new Data();
Data day2 = new Data();
Data day3 = new Data();
day1.setDay(2020,5,10);
day2.setDay(2021,5,10);
day3.setDay(2022,5,10);
day1.printData();
day2.printData();
day3.printData();
}
}
解释:
当形参名与变量名相同是,此时因为局部优先,形参和变量都是局部变量,不是成员变量。
为了防止这种情况出现,我们通常加this-来修饰:
总结:
- 那个对象调用就是那个对象的引用类型。
- this只能在"成员方法"中使用。
- 在“成员方法中”,this只能引用当前对象,不能再引用其他对象。
四、对象的构造及其初始化
构造的特性:
- 名字必须与类名相同。
- 没有返回值类型,设置为void也不行。
- 创建对象时由编译器自动调用,生命周期只有一次。
- 构造方法时可以重载。
当我们创建对象时,编译器会自动生成并调用一次不带参数的构造,然后我们可以对对象进行初始化,但也可以自己写一个带参数的构造,在创建对象时就能完成初始化,这个构造也是只会被调用一次。
例:
public Data(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public static void main(String[] args) {
Data day1 = new Data(2020,5,10);
Data day2 = new Data(2021,5,10);
Data day3 = new Data(2022,5,10);
}
注:
- 当类中已经有了带有参数的构造时,编译器就不会再调用不带参数的构造了。
- 构造方法的作用是给对象中的成员进行初始化,并不负责给对象开辟空间。
- 构造方法也可以重载
方法的重载:
- 方法名相同
- 参数列表不同:个数、类型、顺序。
- 和返回值没关系
public class Data {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printData(){
System.out.println(year + "-" + month + "-" + day);
}
public Data(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public Data(int year, int day) {
this.year = year;
this.day = day;
}
public static void main(String[] args) {
Data day1 = new Data(2020,10);
Data day2 = new Data(2021,5,10);
Data day3 = new Data(2022,5,10);
day1.printData();
day2.printData();
day3.printData();
}
}
- this在一个构造方法中可以调用另一个构造方法
注:
- this必须是构造中的第一个语句。
- 不能在另一个构造中再次this调用,形成闭环。
- 在调用方法时也可以在方法名前加上this func()。
- 就地初始化
在定义字段时,同时初始化:
public class Data {
public int year = 1999;
public int month = 1;
public int day = 2;
}
初始化总结:
- 定义字段时,同时初始化——》就地初始化。
- 不初始化——》0。
- 在类外,通过对象的引用 直接赋值—dog.name = "大黄"。
- 通过构造方法初始化。
五、封装
5.1 封装的概念及实现
- 面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性——套壳隐藏细节。
- 将数据和和操作数据的方法进行结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
范围 | private | default | protected | public |
同一包中的同一类 | ![]() | ![]() | ![]() | ![]() |
同一包中的不同类 | ![]() | ![]() | ![]() | |
不同包中的子类 | ![]() | ![]() | ||
不同包中的非子类 | ![]() |
-
访问限定符
在Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,二访问权限用来控制方法或者字段能否直接在类外使用。
Java提供了四种访问限定符:
- private:只有自己知道,私密。
- public:公开的,谁都能够知道。
- default(什么都不写时的默认权限):对于自己家族的人来说都知道,外人不知道。
- protected:主要用在继承中。
我们可以设置接口来和对象进行交互:
5.2 封装拓展—包
- 包的概念
为了更好地管理类,把多个类收集在一起成为一组,称为软件包,包是对类、接口等的封装机智的体现,是一种对类和接口等很好的组织方式;在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
类似于文件夹目录:
- 导入包中的类
import java.util.Arrays;
public class Test2 {
public static void main(String[] args) {
int[] arr = {1,2,3,4};
System.out.println(Arrays.toString(arr));
}
- 如果需要java.util中的其他类,也可以使用 import java.util.*
import java.util.*;
public class Test2 {
public static void main(String[] args) {
int[] arr = {1,2,3,4};
System.out.println(Arrays.toString(arr));
}
- 两个包中有相同类时,会出现冲突
这时就要写完整导包:
import java.util.*;
import java.sql.*;
public class Test2 {
public static void main(String[] args) {
int[] arr = {1,2,3,4};
java.util.Date date = new java.util.Date();
System.out.println(Arrays.toString(arr));
}
}
- 自定义包
基本规则:
- 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
- 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.66.demo )
- 包名要和代码路径相匹配. 例如创建 com.66.demo 的包, 那么会存在一个对应的路径 com/66/demo1 来存储代码.
- 如果一个类没有 package 语句, 则该类被放到一个默认包中.