一、package包
包的作用
1)区分相同名字的类
2)当类很多时,可以很好的管理类
3)控制访问范围
包的基本语法
package com.spock;
说明:
package 关键字,表示打包
com.spock 表示包名
包的命名规则
只能包含数字、字母、下划线、小圆点,但不能用数字开头,不能是关键字或保留字
demo.class.exec1 //错误,class是关键字
demo.12a //错误,12a是数字开头
demo.ab12.oa // 正确
包名一般是小写字母+小圆点
com.公司名.项目名.业务模块名
com.sina.blog.user //用户模块
com.sina.blog.order //订单模块
常用的包
一个包下,包含很多的类,java 中常用的包有:
java.lang.* //lang 包是基本包,默认引入,不需要再引入。
java.util.* //util 包,系统提供的工具包,工具类,例如 Scanner
java.net.* //网络包,网络开发
java.awt.* //是做 Java 的界面开发,GUI
包的引入
语法:
import 包;
引入一个包的主要目的是要使用该包下的类
比如:
import java.util.Scanner; 就只是引入一个类Scanner
import java.util.*; 表示将java.util包所有类都引入
使用案例
package com.hspedu.pkg;
import java.util.Arrays;
//注意:
//建议:我们需要使用到哪个类,就导入哪个类即可,不建议使用 *导入
//import java.util.Scanner;
//表示只会引入 java.util 包下的 Scanner
//import java.util.*;
//表示将 java.util 包下的所有类都引入(导入)
public class Import01 {
public static void main(String[] args) {
//使用系统提供的 Arrays 完成 数组排序
int[] arr = {-1, 20, 2, 13, 3};
//比如对其进行排序
//传统方法是,自己编写排序(冒泡)
//系统是提供了相关的类,可以方便完成 Arrays
Arrays.sort(arr);
//输出排序结果
for (int i = 0; i < arr.length ; i++) {
System.out.print(arr[i] + "\t");
}
}
}
需要使用到哪个类,就导入哪个类即可,不建议使用 * 导入。
java.lang.* //lang 包是基本包,默认引入,不需要再引入。
注意事项
//package 的作用是声明当前类所在的包,需要放在类(或者文件)的最上面
// 一个类中最多只有一句 package
package com.edu.pkg;
//import 指令 位置放在 package 的下面,在类定义前面,可以有多句且没有顺序要求
import java.util.Scanner;
import java.util.Arrays;
package 的作用是声明当前类所在的包,需要放在类(或者文件)的最上面,一个类中最多只有一句 package。
import 指令的位置放在 package 的下面,在类定义前面,可以有多句且没有顺序要求。
二、访问修饰符
基本介绍
Java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):
1) 公开级别:用 public 修饰,对外公开
2) 受保护级别:用 protected 修饰,对子类和同一个包中的类公开
3) 默认级别:没有修饰符号,向同一个包的类公开.
4) 私有级别:用 private 修饰,只有类本身可以访问,不对外公开
访问范围
访问级别 | 访问修饰符 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | Public | √ | √ | √ | √ |
受保护 | Protected | √ | √ | √ | × |
默认 | 无修饰符 | √ | √ | × | × |
私有 | Private | √ | × | × | × |
注意事项
1)修饰符可以用来修饰类中的属性,成员方法以及类。
2)只有默认的和 public 才能修饰类,并且遵循上述访问权限的特点
3)成员方法的访问规则和属性完全一样
三、面向对象编程三大特征
面向对象编程有三大特征:封装、继承和多态。
四、面向对象编程-封装
基本介绍
封装(encapsulation)就是把抽象出来的数据 [属性] 和对数据的操作 [方法] 封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作 [方法],才能对数据进行操作。
封装的作用
1)隐藏实现细节:方法(连接数据库) <---- 调用(传入参数)
2)可以对数据进行验证,保证安全合理
Person {name, age}
Person p = new Person();
p.name = "jack";
p.age = 100;
封装的实现步骤
1)将属性进行私有化 private 【不能直接修改属性】
2)提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型 参数名) {
//加入数据验证的业务逻辑
属性 = 参数名;
}
3)提供一个公共的(public)get方法,用于获取属性的值
public 数据类型 getXxx() {
return xxx;
}
使用案例
class Person {
public String name; //名字公开
private int age; //age 私有化
private double salary; //..
//构造器 alt+insert
public Person() {
}
//自己写 setXxx 和 getXxx 太慢,我们使用快捷键 alt+insert
//然后根据要求来完善我们的代码.
public String getName() {
return name;
}
public void setName(String name) {
//加入对数据的校验,相当于增加了业务逻辑
if(name.length() >= 2 && name.length() <=6 ) {
this.name = name;
}else {
System.out.println("名字的长度不对,需要(2-6)个字符,默认名字");
this.name = "无名人";
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
//判断
if(age >= 1 && age <= 120) {
//如果是合理范围
this.age = age;
} else {
System.out.println("你设置年龄不对,需要在 (1-120), 给默认年龄 18 ");
this.age = 18;//给一个默认年龄
}
}
public double getSalary() {
//可以这里增加对当前对象的权限判断
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
五、面向对象编程-继承
基本介绍
继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中 抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends 来声明继承父类即可。
继承的基本语法
class 子类 extends 父类 {
}
1)子类会自动拥有父类定义的属性和方法
2)父类又叫超类,基类
3)子类又叫派生类
继承的作用
1)提高代码的复用性
2)提高代码的扩展性和维护性
使用案例
//Student类, 是 Pupil 和 Graduate 的父类
public class Student {
//共有属性
public String name;
public int age;
private double score;//成绩 //共有的方法
public void setScore(double score) {
this.score = score;
}
public void showInfo() {
System.out.println("学生名 " + name + " 年龄 " + age + " 成绩 " + score);
}
}
//子类
public class Pupil extends Student {
public void testing() {
System.out.println("小学生 " + name + "正在考小学数学..");
}
}
//子类
public class Graduate extends Student {
public void testing() { //和 Pupil 不一样
System.out.println("大学生 " + name + " 正在考大学数学..");
}
}
继承的使用细节
1) 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问
但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
2) 子类必须调用父类的构造器,完成父类的初始化
3) 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器
如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的某个构造器完成对父类的初始化工作
否则,编译不会通过
public Sub() {
//无参构造器
super(); //默认调用父类的无参构造器,可以不写
System.out.println("子类 Sub()构造器被调用....");
}
4) 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
//当创建子类对象时,不管使用子类的哪个构造器
//默认情况下总会去调用父类的无参构造器
//如果要修改使用super指定
public Sub(String name) {
super("tom", 30);//调用父类两个参数的构造器
//do nothing...
System.out.println("子类 Sub(String name)构造器被调用....");
}
5) super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
6) super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
7) java 所有类都是 Object 类的子类, Object 是所有类的基类
8) 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(*父类)
9) 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。
思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】
10) 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系。xxx是一个xxx
六、super 关键字
基本介绍
super 代表父类的引用,用于访问父类的属性、方法、构造器。
基本语法
1)访问父类的属性,但不能访问父类的 private属性
super.属性名;
2)访问父类的方法,但不能访问父类的 private方法
super.方法名(参数列表);
3)访问父类的构造器
super(参数列表);
只能放在构造器的第一句,只能出现一句
Super的使用细节
1)调用父类的构造器的好处
(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
2)当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。
如果没有重名,使用super、this、直接访问是一样的效果!
3)super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;
如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C,当然也需要遵守访问权限的相关规则。
super 和 this 的比较
NO | 区别点 | This | Super |
---|---|---|---|
1 | 访问属性 | 访问本类中的属性,如果本类没有此属性则从父类继续查找。 | 从父类开始查找属性。 |
2 | 调用方法 | 访问本类中的方法,如果本类没有此方法则从父类继续查找。 | 从父类开始查找方法。 |
3 | 调用构造器 | 调用本类的构造器,必须放在构造器的首行。 | 调用父类构造器,必须放在子类构造器的首行。 |
4 | 特殊 | 表示当前对象 | 子类中访问父类对象 |
注:本博客引用韩顺平老师Java课程