面向对象(上)
文章目录
1.1、面向对象概述
- 面向对象与面向过程
- 二者都是一种思想,面向对象是相对于面向过程而言的。面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
- 面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。
- 类(Class)和对象(Object)是面向对象的核心概念。
- 类是对一类事物的描述,是抽象的、概念上的定义
- 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
- 类
- 类的组成是由属性和行为两部分组成
- 属性:在类中通过成员变量来体现(类中方法外的变量)
- 行为:在类中通过成员方法来体现(和前面的方法相比去掉 static关键字即可)
- 类的定义
定义格式
修饰符 class 类名 {
属性声明;
方法声明;
}
说明: 修饰符public :类可以被任意访问
类的正文要用{ }
如:
public class Person{
private int age ; // 声明私有变量 age
public void showAge(int i) { // 声明方法showAge( )
age = i;
}
}
1.2、对象的创建与使用
- 对象创建
- 创建对象语法: 类名 对象名 = new 类名();
- 使用**“对象名. 对象成员 ”**的方式访问对象成员(包括属性和方法)
//实例
//创建一个动物类
public class Animal {
public int legs;//定义一个成员变量
public void eat(){//定义方法eat
System.out.println(“Eating.”);
}
public viod move(){//定义方法move
System.out.println(“Move.”);
}
}
//一个含有main方法的类,用来调用动物类中的变量和方法
public class Zoo{
public static void main(String args[]){
// 创建对象
Animal xb=new Animal();
xb.legs=4;// 访问属性
System.out.println(xb.legs);
xb.eat();// 访问方法
xb.move();// 访问方法
}
}
**注意:**如果 创建了一个类的多个对象,对于类中定义的属性,每个对象都拥有各自的一套副本,且互不干扰。
//实例
//定义一个电话类
public class Phone {
//成员变量
String brand;
int price;
//成员方法
public void call() {
System.out.println("打电话");
}
public void sendMessage() {
System.out.println("发短信");
}
}
//在主类中进行调用
/*
创建对象
格式:类名 对象名 = new 类名();
范例:Phone p = new Phone();
使用对象
1:使用成员变量
格式:对象名.变量名
范例:p.brand
2:使用成员方法
格式:对象名.方法名()
范例:p.call()
*/
public class PhoneDemo {
public static void main(String[] args) {
//创建对象
Phone p = new Phone();//使用成员变量
System.out.println(p.brand);
System.out.println(p.price);
p.brand = "小米";
p.price = 2999;
System.out.println(p.brand);
System.out.println(p.price);
//使用成员方法
p.call();
p.sendMessage();
}
}
注意:类的访问机制
- 在一个类中的访问机制: 类中的方法可以直接访问类中的成员变量 。(例外:static 方法访问非 static,编译不通过 。
- 在不同类中的访问机制: 先创建要访问类的对象 , 再用对象访问类中定义的成员 。
1.3、对象内存解析
- 存储区的介绍
- 堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
- 通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char 、 short 、 int 、 float 、 long 、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
- 方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
注意:当多个对象的引用指向同一个内存空间(变量所记录的地址值是一样的)只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。其实际上传递的是内存地址。
- 局部变量和成员变量
- 成员变量(类中方法外)局部变量(方法内部或方法声明上)
- 成员变量(堆内存)局部变量(栈内存)
- 成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而存在,醉着方法的调用完毕而消失)
- 成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)
package com.atguigu.java;
/*
* 类中属性的使用
*
* 属性(成员变量) vs 局部变量
* 1.相同点:
* 1.1 定义变量的格式:数据类型 变量名 = 变量值
* 1.2 先声明,后使用
* 1.3 变量都有其对应的作用域
*
*
* 2.不同点:
* 2.1 在类中声明的位置的不同
* 属性:直接定义在类的一对{}内
* 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
*
* 2.2 关于权限修饰符的不同
* 属性:可以在声明属性时,指明其权限,使用权限修饰符。
* 常用的权限修饰符:private、public、缺省、protected --->封装性
* 目前,大家声明属性时,都使用缺省就可以了。
* 局部变量:不可以使用权限修饰符。
*
* 2.3 默认初始化值的情况:
* 属性:类的属性,根据其类型,都有默认初始化值。
* 整型(byte、short、int、long):0
* 浮点型(float、double):0.0
* 字符型(char):0 (或'\u0000')
* 布尔型(boolean):false
*
* 引用数据类型(类、数组、接口):null
*
* 局部变量:没有默认初始化值。
* 意味着,我们在调用局部变量之前,一定要显式赋值。
* 特别地:形参在调用时,我们赋值即可。
*
* 2.4 在内存中加载的位置:
* 属性:加载到堆空间中 (非static)
* 局部变量:加载到栈空间
*
*/
public class UserTest {
public static void main(String[] args) {
User u1 = new User();
System.out.println(u1.name);
System.out.println(u1.age);
System.out.println(u1.isMale);
u1.talk("韩语");
u1.eat();
}
}
class User{
//属性(或成员变量)
String name;
public int age;
boolean isMale;
public void talk(String language){//language:形参,也是局部变量
System.out.println("我们使用" + language + "进行交流");
}
public void eat(){
String food = "烙饼";//局部变量
System.out.println("北方人喜欢吃:" + food);
}
}
- 匿名对象
-
我们也可以不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。
new Person().shout();
-
如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
-
我们经常将匿名对象作为实参传递给一个方法调用。
1.4、类的成员
1.4.1、属性
- 语法格式
修饰符 数据类型 属性名 = 初始化值;
- 常用的修饰符
- 常用的权限修饰符有:private、缺省、protected、public
- 其他修饰符:static、final
public class Person{
private int age; // 声明private变量 age
public String name = “Lila”; //声明public变量 name
}
class User{
//属性(或成员变量)
String name;
public int age;
boolean isMale;
public void talk(String language){//language:形参,也是局部变量
System.out.println("我们使用" + language + "进行交流");
}
public void eat(){
String food = "烙饼";//局部变量
System.out.println("北方人喜欢吃:" + food);
}
}
1.5、方法
- 方法的定义
- 方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程。
- 将功能封装为方法的目的是,可以实现代码重用,简化代码
- Java里的方法不能独立存在,所有的方法必须定义在类里。
- 方法的声明格式
修饰符 返回值类型 方法名 ( 参数类型 形参1, 参数类型 形参2, …){
方法体程序代码
return 返回值;
}
//修饰符:public, 缺省,private, protected
//没有返回值:void。
//有返回值,声明出返回值的 类型。与方法体中“ “return ” 返回值”
//返回值:方法在执行完毕后返还给调用它的程序的数据。
- 方法的调用
方法通过方法名被调用,且只有被调用才会执行。
- 注意
- 方法被调用一次,就会执行一次
- 没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
- 定义方法时,方法的结果应该返回给调用者,交由调用者处理。
- 方法中只能调用方法或属性,不可以在方法内部定义方法。
- 总结
package com.atguigu.java;
/*
* 类中方法的声明和使用
*
* 方法:描述类应该具有的功能。
* 比如:Math类:sqrt()\random() \...
* Scanner类:nextXxx() ...
* Arrays类:sort() \ binarySearch() \ toString() \ equals() \ ...
*
* 1.举例:
* public void eat(){}
* public void sleep(int hour){}
* public String getName(){}
* public String getNation(String nation){}
*
* 2. 方法的声明:权限修饰符 返回值类型 方法名(形参列表){
* 方法体
* }
* 注意:static、final、abstract 来修饰的方法,后面再讲。
*
* 3. 说明:
* 3.1 关于权限修饰符:默认方法的权限修饰符先都使用public
* Java规定的4种权限修饰符:private、public、缺省、protected -->封装性再细说
*
* 3.2 返回值类型: 有返回值 vs 没有返回值
* 3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用
* return关键字来返回指定类型的变量或常量:“return 数据”。
* 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要
* 使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思。
*
* 3.2.2 我们定义方法该不该有返回值?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.3 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
*
* 3.4 形参列表: 方法可以声明0个,1个,或多个形参。
* 3.4.1 格式:数据类型1 形参1,数据类型2 形参2,...
*
* 3.4.2 我们定义方法时,该不该定义形参?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.5 方法体:方法功能的体现。
*
* 4.return关键字的使用:
* 1.使用范围:使用在方法体中
* 2.作用:① 结束方法
* ② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
* 3.注意点:return关键字后面不可以声明执行语句。
*
* 5. 方法的使用中,可以调用当前类的属性或方法
* 特殊的:方法A中又调用了方法A:递归方法。
* 方法中,不可以定义方法。
*/
public class CustomerTest {
public static void main(String[] args) {
Customer cust1 = new Customer();
cust1.eat();
//测试形参是否需要设置的问题
// int[] arr = new int[]{3,4,5,2,5};
// cust1.sort();
cust1.sleep(8);
}
}
//客户类
class Customer{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat(){
System.out.println("客户吃饭");
return;
//return后不可以声明表达式
// System.out.println("hello");
}
public void sleep(int hour){
System.out.println("休息了" + hour + "个小时");
eat();
// sleep(10);
}
public String getName(){
if(age > 18){
return name;
}else{
return "Tom";
}
}
public String getNation(String nation){
String info = "我的国籍是:" + nation;
return info;
}
//体会形参是否需要设置的问题
// public void sort(int[] arr){
//
// }
// public void sort(){
// int[] arr = new int[]{3,4,5,2,5,63,2,5};
//
// }
public void info(){
//错误的
// public void swim(){
//
// }
}
}
- 练习
计算圆的面积
package com.method;
public class Circle {
public double fidArea(double radius){
return Math.PI * radius * radius;
}
}
//主类
package com.method;
import java.util.Scanner;
public class CircleMain {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入圆的半径:");
double radius = scanner.nextDouble();
double fidArea = new Circle().fidArea(radius);
System.out.println("圆的面积为:" + fidArea);
}
}
对象数组
package com.method;
public class Student {
int number;//学号
int score;//成绩
int state;//年级
}
//主类
package com.method;
/**
* 对象数组题目:
* 定义类Student,包含三个属性:学号number(int),年级state(int),成绩
* score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
* 问题一:打印出3年级(state值为3)的学生信息。
* 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
* 提示:
* 1) 生成随机数:Math.random(),返回值类型double;
* 2) 四舍五入取整:Math.round(double d),返回值类型long。
*/
public class StudentMain {
public static void main(String[] args) {
Student[] students = new Student[20];
//动态生成20个对象
for (int i = 0; i < students.length; i++) {
students[i] = new Student();
students[i].number = (i + 1);
students[i].state = (int) (Math.random() * (6 - 1 + 1) + 1);//随机数[1,6]
students[i].score = (int) (Math.random() * (100 - 0 + 1) + 1);//随机数[0,100]
}
//遍历数组
for (int i = 0; i < students.length; i++) {
System.out.println(students[i].number + "\t" + students[i].score + "\t"
+ students[i].state + "\t");
}
System.out.println("================================");
//打印出3年级(state值为3)的学生信息。
for (int i = 0; i < students.length; i++) {
if (students[i].state == 3){
System.out.println(students[i].number + "\t" + students[i].score + "\t"
+ students[i].state + "\t");
}
}
System.out.println("================================");
//使用冒泡排序按学生成绩排序,并遍历所有学生信息
for (int i = 0; i < students.length - 1; i++) {
for (int j = 0; j < students.length - i -1; j++) {
if (students[j].score > students[j+1].score){
Student temp = students[j];
students[j] = students[j+1];
students[j+1] = temp;
}
}
}
//遍历数组
for (int i = 0; i < students.length; i++) {
System.out.println(students[i].number + "\t" + students[i].score + "\t"
+ students[i].state + "\t");
}
}
}
1.5.1、自定义数组的工具类
定义数组的工具类ArrayUtil,方便进行数组操作
package com.atguigu.java;
/*
* 自定义数组的工具类
*
*/
public class ArrayUtil {
// 求数组的最大值
public int getMax(int[] arr) {
int maxValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (maxValue < arr[i]) {
maxValue = arr[i];
}
}
return maxValue;
}
// 求数组的最小值
public int getMin(int[] arr) {
int minValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (minValue > arr[i]) {
minValue = arr[i];
}
}
return minValue;
}
// 求数组的总和
public int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
// 求数组的平均值
public int getAvg(int[] arr) {
return getSum(arr) / arr.length;
}
//如下的两个同名方法构成了重载
// 反转数组
public void reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
}
// 复制数组
public int[] copy(int[] arr) {
int[] arr1 = new int[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
return arr1;
}
// 数组排序
public void sort(int[] arr) {
// 冒泡排序
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr,j,j + 1);
}
}
}
}
//正确的:交换数组中指定两个位置元素的值
public void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 遍历数组
public void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
// 查找指定元素
public int getIndex(int[] arr, int dest) {
// 线性查找:
for (int i = 0; i < arr.length; i++) {
if (dest == arr[i]) {
return i;
}
}
return -1;//返回一个负数,表示没有找到
}
}
1.5.2、方法重载
- 什么是方法重载
在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可
- 怎样方法重载
与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
- 实例
public class PrintStream {
public static void print(int i) {……}
public static void print(float f) {……}
public static void print(String s) {……}
public static void main(String[] args) {
print(3);
print(1.2f);
print("hello!");
}
}
//
//返回两个整数的和
int add(int x,int y){return x+y;}
//返回三个整数的和
int add(int x,int y,int z){return x+y+z;}
//返回两个小数的和
double add(double x,double y){return x+y;}
1.5.3、方法中的参数——可变形参
- 什么是可变形参?
可变形参就是方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
- 如何声明?
声明格式:方法名(参数的类型名 …参数名)
- 注意
- 可变个数形参的方法与同名的方法之间,彼此构成重载
- 可变参数方法的使用与方法参数部分使用数组是一致的
- 方法的参数部分有可变形参,需要放在形参声明的最后
- 在一个方法的形参位置,最多只能声明一个可变个数形参
1.5.4、值传递
方法,必须由其 所在类或对象调用才有意义。若方法含有参数:
形参:方法声明时的参数
实参:方法调用时实际传给形参的参数值
- 中心问题
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
1.5.5、递归调用
递归方法:一个方法体内调用它自身
- 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
- 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
//计算1-100之间所有自然数的和
public int sum(int num){
if(num == 1){
return 1;
} else {
return num + sum(num - 1);
}
}
1.6、面向对象——封装性
当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受到
属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值
加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。(比如:setLegs())
同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private).
–>此时,针对于属性就体现了封装性。
我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
- 封装性的体现
- Java规定的4种权限(从小到大排列):private、缺省、protected 、public
- 4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
- 具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类修饰类的话,只能使用:缺省、public
- 代码演示
定义一个实体类
package com.method;
//实体类User
public class User {
private String name;
private int age;
private double score;
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 double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
在主类中调用实体类中的属性
package com.method;
public class UserMain {
public static void main(String[] args) {
User user = new User();
user.setAge(12);
user.setName("小明");
user.setScore(12.32);
System.out.println(user.getAge());
System.out.println(user.getName());
System.out.println(user.getScore());
}
}
- 权限修饰符
直观理解
1.7、构造器
构造器(或构造方法、constructor)的作用:
- 创建对象
- 初始化对象信息
- 说明
- 如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
- 定义构造器的格式:权限修饰符 类名(形参列表){}
- 一个类中定义的多个构造器,彼此构成重载
- 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
- 一个类中,至少会有一个构造器。
-
语法格式
修饰符 名 类名 ( 参数列表) {
初始化 语句;
} -
示例
package com.construct;
public class Person {
private int id;
private int age;
private String name;
//无参构造器
public Person() {
System.out.println("无参构造被调用了");
}
//含参构造器
public Person(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
//get与set方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//主类
package com.construct;
public class PersonMain {
public static void main(String[] args) {
Person person = new Person();
//输出:无参构造被调用了
}
}
- 注意
- 它具有与类相同的名称
- 它不声明返回值类型。(与声明为void不同)
- 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
- 构造器一般用来创建对象的同时初始化对象。
- 构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。构造器重载,参数列表必须不同
- 什么是JavaBean
JavaBean是一种Java语言写成的可重用组件。
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
- 示例
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类图
1.8、this关键字的使用
- this关键字是什么?
- 它在方法内部使用,即这个方法所属对象的引用;
- 它在构造器内部使用,表示该构造器正在初始化的对象。
- this关键字可以做什么?
- this 可以调用类的属性、方法和构造器
- 什么时候使用this关键字?
- 当在方法内需要用到调用该方法的对象时,就用this。具体的:我们可以用this来区分属性和局部变量。比如:this.name = name;
- 在任意方法或构造器内,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的阅读性。不过,通常我们都习惯省略this。
- 当形参与成员变量同名时,如果在方法内或构造器内需要使用成员变量,必须添加this来表明该变量是类的成员变量
- 使用this访问属性和方法时,如果在本类中未找到,会从父类中查找
- this可以作为一个类中构造器相互调用的特殊格式
- 注意
- 可以在类的构造器中使用"this(形参列表)"的方式,调用本类中重载的其他的构造器!
- 明确:构造器中不能通过"this(形参列表)"的方式调用自身构造器
- 如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(形参列表)"
- "this(形参列表)"必须声明在类的构造器的首行!
- 在类的一个构造器中,最多只能声明一个"this(形参列表)"
- 示例
package com.atguigu.java2;
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(){
// this.eat();
String info = "Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)";
System.out.println(info);
}
public Person(String name){
this();//指向构造器
this.name = name;//将形参name的值赋值给成员变量name
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);
this.name = name;
//this.age = age;
//Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void eat(){
System.out.println("人吃饭");
this.study();
}
public void study(){
System.out.println("人学习");
}
}
1.9、package关键字
package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。
- 格式
package 顶层包名.子包名 ;
- 含义
- 包对应于文件系统的目录,package 语句中,用 “.” 包 来指明包( 目录) 的层次;
- 包通常用 小写: 单词标识。通常使用所在公司域名的倒置:com.xxx
- 作用
- 包帮助管理大型软件系统:将功能相近的类划分到同一个包中。比如:MVC的设计模式
- 包可以包含类和子包,划分项目层次,便于管理
- 解决类命名冲突的问题
- 控制访问权限
2.0、MVC设计模式
2.1、import关键字
为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类(.*)。import语句告诉编译器到哪里去寻找类。
- 格式
import 包名.类名;
- 注意
- 在源文件中使用import显式的导入指定包下的类或接口
- 声明在包的声明和类的声明之间。
- 如果需要导入多个类或接口,那么就并列显式多个import语句即可
- 举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。
- 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
- 如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类。
- 如果已经导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。
- import static组合的使用:调用指定类或接口下的静态的属性或方法