1. This
1.1 是什么
* this 是什么 : 是每个对象中,保存自身内存地址的一个引用类型变量
* this就表示当前对象
1.2 能做什么
* 1 在成员方法或者构造方法中,区分同名的成员变量和局部变量
* this.xxx
* 2 用在构造方法中,重载调用当前类中其他构造方法,但是必须写在构造方法第一行
* this(xxx)
* 3 return this 返回当前对象的内存地址,可以链式调用
1.3 怎么用
1.3.1 区分成员和局部
public class This_01 {
public static void main(String[] args){
int a = 2;
int b = 2;
// 静态变量可以和局部变量同名
// 局部变量优先级更高
// 可以使用类名区分同名的静态变量和局部变量
// 静态变量可以和局部变量同名
// 局部变量优先级更高
// 可以使用类名区分同名的静态变量和局部变量
System.out.println(a);
System.out.println(This_01.b);
System.out.println(b);
}
// 成员变量
int d = 2;
public void m1() {
// 成员变量可以和局部变量同名
// 局部变量优先级更高
// 可以使用this区分同名的成员变量和局部变量
int c = 2;
System.out.println(c);
System.out.println(d);
int d = 3;
System.out.println(d);
System.out.println(this.d);
}
class MyDate {
private int year;
private int month;
private int day;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
1.3.2 重载调用构造方法
public MyDate() {
// this.year = 1970;
// this.month = 1;
// this.day = 1;
// 上面代码 也是可以实现的,但是偏离代码复用的本质,而且也影响代码美观和可读性
// 调用当前类的指定构造方法
// 但是 该写法 只能写在构造方法中,并且必须是在第一行
this(1970, 1, 1);
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
1.3.3 链式调用
package day_02._01_This;
public class This_02 {
public static void main(String[] args) {
This_02 t = new This_02();
t.m1();
t.m2();
// 链式调用
t.m1().m2();
}
public This_02 m1() {
System.out.println("m1");
return this;
}
public void m2() {
System.out.println("m2");
}
}
1.4 注意
This 不能出现在静态上下文中
2. Static
2.1 是什么
修饰符,关键字,用来区分静态和成员
2.2 能做什么
* static 能做什么
* 1 在类体中使用static修饰的变量 是 静态变量
* 2 用static修饰的方法,是静态方法
* 3 还可以使用static定义静态语句块
2.3 静态语句块
public class Static_01 {
public static void main(String[] args) {
System.out.println("=========");
System.out.println(i);
}
// 静态变量
static int i = 2;
// 静态方法
public static void m1(){
}
// 静态语句块,等同于静态方法
// 静态语句块自动执行,在程序加载阶段执行完成,并且只执行一次
// 由于执行时机是在main之前,并且只执行一次,所以非常适合做一些初始化工作
// 访问一个类的静态属性的时候,类加载
static{
System.out.println("----------");
}
// 多个static语句块,从上往下执行
static{
System.out.println("-----222");
}
}
2.4 实例语句块
* 实例语句块 可以看做成员方法,没有static修饰的语句块就是成员语句块
*
* 创建对象之后,立刻执行 , 每创建一个对象,就执行一次 并且在构造方法之前
public class Static_02 {
{
System.out.println("实例语句块1");
}
{
System.out.println("实例语句块2");
}
static{
System.out.println("静态语句块");
}
Static_02(){
System.out.println("构造方法");
}
public static void main(String[] args) {
System.out.println("main方法");
new Static_02();
new Static_02();
}
}
3. 封装
把所有组成部分组合到一起,还可以通过权限控制修饰符将数据隐藏起来,可以控制用户对类数据的修改程度
适当的封装可以让代码更容易理解,易于维护,更提高了代码的安全性
3.1 包机制
3.1.1 Package
* package : 软件包机制
* 1 主要解决了命名冲突问题,在类名前加命名空间
* 2 完整的类名是带有包名的 , 包名.类名 才是这个类的名字
* 3 package语句 必须出现在java源文件的第一行
* 4 package语句是 规定编译之后的class文件保存的位置,和源文件无关
* 5 命名规则 一般采用公司域名倒叙
* com.tledu.oa.system
3.1.2 Import
* import 语句 用于把当前类中需要的其他类,载入
*
* 必须出现在class语句之上,package语句之下
*
* java.lang.* : 该包下所有类均为系统核心类,使用时不需要导入
*
* 注意 : 按空格 或者回车的时候 会自动导包,如果程序没有问题,但是报错,可以查看一下是否导包错误
package day_02._03_Package;
// 导入时间类
import java.util.Date;
// .* 表示导入util下所有类
import java.util.*;
public class Package_02 {
public static void main(String[] args) {
// 因为A和当前类在同包下,所以直接写类名即可找到A
System.out.println(A.i);
// 只要不在同包下,必须通过 包名.类名 才能找到该类
day_02._03_Package.pojo.User user = new day_02._03_Package.pojo.User();
User user1 = new User();
Date date = new Date();
String string = "";
}
}
注意 : 按空格 或者回车的时候 会自动导包,如果程序没有问题,但是报错,可以查看一下是否导包错误
package day_02._03_Package;
// 静态导入,把一个类中的静态属性导入,在当前类中可以直接写名字调用,可以省略类名
import static day_02._03_Package.pojo.User.*;
import day_02._03_Package.pojo.User;
public class Package_03 {
public static void main(String[] args) {
System.out.println(User.age);
System.out.println(age);
System.out.println(name);
}
}
3.2 权限控制
* public : 公共的 哪里都能访问
*
* private : 只能在当前类访问
*
* default : 不写权限控制修饰符,默认为default , 同包中 即可访问
*
* protected : 受保护的,继承权限,要么同包,要么有继承关系
public static void main(String[] args) {
// 同包测试
// 公共的 可以
System.out.println(A.a);
// 私有的 不行
// System.out.println(A.b);
// 默认的 可以
System.out.println(A.c);
// 受保护的 可以
System.out.println(A.d);
// 不同包测试
// 公共的 可以
System.out.println(B.a);
// 私有的 不行
// System.out.println(B.b);
// 默认的 不行
// System.out.println(B.c);
// 受保护的 不行
// System.out.println(B.d);
}
4. 继承
4.1 是什么
* 继承 : 就是在已有的类中派生出新的类,新的类能吸收已有类的属性和行为
*
* java中 只支持单继承,不支持多继承,并且继承可以传递
*
* 一个类只能继承一个父类,但是一个类可以被很多子类继承
4.2 能做什么
* 继承目的 : 代码复用,提高效率,如果父类满足不了子类需求的话,还可以进行覆写,可以使用多态
*
* 如果一个类没有显示继承一个类,那么该类 默认继承 Object
* java.lang.Object 是Java中提供的根类,所有类都会直接或者间接性的继承这个类
4.3 怎么用
语法 : class 类名 extends 父类名 {类体 }
public class SupClass {
protected void m2(){
System.out.println("我是父类m2");
}
}
public class SubClass extends SupClass{
public void m1(){
System.out.println("我是子类m1");
}
}
public class Extends_01 {
public static void main(String[] args) {
SubClass sub = new SubClass();
sub.m1();
sub.m2();
}
}
5. Super
5.1 是什么
super : 官方说法是 代表了父类的特征
5.2 能做什么
* 1 用在成员方法和构造方法中 区分父子类之间同名的方法和变量
* super.xxx
* 2 用在子类构造方法中,调用指定的父类构造方法
* super(xxx);
* 如果在子类构造方法中,没有显示出现super() 也没有出现 this(xxx) 则 默认有一个super() 调用父类无参构造
* 并且 super(xxx) 必须出现在子类构造方法 第一行 所以 this(xxx) 和 super(xxx) 不能同时出现
5.3 怎么用
5.3.1 区分父子类同名的属性
public class SubClass extends SupClass{
int age = 19;
public void m1(){
System.out.println("子类m1");
}
public void m2(){
// 子类
m1();
// 子类
System.out.println(age);
// 父类
System.out.println(name);
// 父类
super.m1();
// 父类
System.out.println(super.age);
}
}
public class SupClass {
int age = 18;
String name = "张三";
public void m1() {
System.out.println("父类m1");
}
}
5.3.2 调用父类的构造方法
public class SubClass extends SupClass{
SubClass(){
super(1);
System.out.println("子类构造");
}
public class SupClass {
SupClass(int i) {
super();
System.out.println("父类构造");
}
5.4 注意
如果在子类构造方法中,没有显示出现super() 也没有出现 this(xxx) 则 默认有一个super() 调用父类无参构造
并且 super(xxx) 必须出现在子类构造方法 第一行 所以 this(xxx) 和 super(xxx) 不能同时出现
因为构造方法第一行有super()调用父类构造,所以 某一个类如果构造方法私有化了,那么该类不会再被继承
6. 覆写/重写
6.1 是什么
* 覆写/重写 : 写一个和父类一样的方法,但是功能 不一样
*
* 1 方法名,返回值,参数列表 必须和父类一致
*
* 2 不能比原方法拥有更低的访问权限
*
* 3 不能比原方法拥有更宽泛的异常
覆写 特指成员方法, 也就是 只有成员方法 可以覆写
6.2 应用场景
当父类功能无法满足子类需求的时候,进行覆写
class Animal {
public void eat() {
System.out.println("动物吃东西");
}
public void move() {
System.out.println("动物在移动");
}
}
class Cat extends Animal {
// @Override : 是源码注解,在编译的时候会判断该方法是否为覆写的方法,防止拼写错误等,如果写错了就会报错
// 如果不加这个注解,也是没关系的,只不过 比如方法名写错了,此时不算覆写了,但是也不会报错
// 所以 加上这个注解 可以降低错误率 , 并且 该注解在编译为class文件后,就会被去掉
@Override
public void eat() {
// 此时 Animal中的eat方法,已经不能满足子类需求了,所以进行覆写
System.out.println("猫吃鱼");
}
}