面向对象
1.This
1.1.概念
this:是每个对象中保存自身内存地址的一个引用类型变量,即this指的是当前对象
1.2.能做什么
- 在成员方法/构造方法中,使用this.变量来区分同名的成员变量和局部变量
- 在构造方法中,可以冲在调用当前对象的其他构造方法(必须在构造方法第一行)
- return this 可以做到链式调用
1.3.怎么用
1.3.1.区分成员和局部
class MyDate{
private int year;//成员变量
public int getYear() {
return year;
}
public void setYear(int year) {//局部变量
this.year = year;//前面的year有this修饰,所以是成员变量,后面的year则是局部变量
}
}
1.3.2.重载调用构造方法
public MyDate() {
//重载调用当前类的其他构造方法
//this()只能在构造方法中,并且只能在构造方法中的第一行
this(1970,1,1);//相当于调用了下面那个构造方法,不影响后续代码执行
System.out.println("无参构造");
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
1.3.3.链式调用
public class Code {
public static void main(String[] args) {
Code code =new Code();
// 链式调用
// 只要前者的返回值是能够调用后者的对象,那就可以链式调用
code.m2().m1();
}
public void m1(){
System.out.println("m1执行了");
}
public Code m2(){
System.out.println("m2执行了");
return this;
}
}
1.4.注意
this不能在静态方法中使用
2.Static
2.1.是什么
static是修饰符,用于区分静态和成员属性
2.2.能做什么
- 使用static修饰的变量是静态变量
- 使用static修饰的方法是静态方法
- 是用static修饰的语句块/代码块是静态语句块
2.3.静态语句块
static{
System.out.println("静态语句块");
}
static{}可以看做一个没有名字的方法,不能复用,只能执行一次
程序加载时,会自动调用静态语句块,并且整个类生命周期中只执行一次
访问一个类静态属性时,会加载该类
由于静态语句块最先执行,并且只执行一次,所以适合做一些类初始化相关工作
静态加载:运行该类时,会把相关用到的所有资源全部一次性载入
动态加载:运行该类时,只会加载当前类,当用到其他类的时候,再去加载其他类
Java中使用的是动态加载
2.4.实例语句块
{
System.out.println("实例语句块");
}
实例语句块可以看做没有名字的成员方法,只有一对大括号{}
每次创建对象时,实例语句块都会执行,并且在构造方法之前执行
执行顺序: 静态–>main -->实例–>构造
3.封装
3.1.包机制
3.1.1.Package
- 软件包机制:可以将文件进行分类管理,并且可以解决命名冲突问题
- package限制的是class文件的存放位置,与java源文件无关,即java源文件无固定位置
- package语句必须在文件第一行
- 带有package的代码,编译和运行方法
编译:javac -d 生成路径 java源文件路径
javac -d ./ -encoding utf-8 xxx.java
运行:java 包名.类名
java com.Test
3.1.2.Import
import用于导入用到的其他类,在当前类中就可以直接写类名进行使用
可以有多个import,但是必须在class语句之上,package语句之下
如果用到的是java.lang.* 类则不需要导入,因为java.lang包下为核心类
// 导入某个包下的某个类
import java.util.Scanner;
// 导入某个包下所有的类
import Day_10.com.*;
// 静态导入,这样我们在当前类中访问该类中的静态属性时,就不需要加类名.调用了,直接写名字调用即可 但是不推荐使用
import static Day_10.com.User.name;
import static Day_10.com.User.*;
public class Package_03 {
public static void main(String[] args) {
User u = new User();
Scanner sc = new Scanner(System.in);
// 核心包下的类可以直接使用
java.lang.String s = "";
String s1 = "";
// 使用其他类中的静态变量,需要 类名.静态变量名
System.out.println(User.age);
// 静态导入后,可以直接通过名字使用
System.out.println(name);
}
}
3.1.3.注意
我们进行编码时,按空格/回车时,可能会自动进行导包
一旦该类存在多个的话,很有可能会导入一个错误的包,需要仔细观察再导入
//import java.sql.Date; 自动导入的错误包
import java.util.Date;//手动导入正确的包
Date date = new Date();
3.2.权限控制
public : 公共的,在哪里都可以访问,只要能找到就行
private : 私有的,只能在当前类中使用当前类的私有化属性,其他类无法使用
prtected : 继承权限,受保护,同包可以使用,或者是有继承关系时,通过子类使用
default : 如果不写权限控制,则为包权限,只有同包的类可以使用,其他地方无法使用
4.继承
4.1.是什么
继承是从已有的类中派生出来的新的类,新的类能吸收以后类的属性和行为,并且还能扩展新的属性和行为(就是你继承你父亲的财产后 你现在的财产=你原本的财产+你父亲的财产,你既可以使用你自己的财产也可以使用你父亲的财产)
java中只支持单继承,一个类只能有一个父类,但是可以被很多类继承(就是你只能有一个亲生父亲,但是你父亲可以有很多孩子)
java中继承是可以传递的(你爸继承你爷爷的,你继承你爸的)
引入继承可以有效提高代码复用性
语法:class 类名 extends 父类名{}
当一个类没有显示继承另一个类的时候,则默认继承java.lang.Object,Object是java提供的根类(所有类都默认继承Object类)
私有化属性是不能继承的(你爸的肿瘤没办法继承给你)
4.2.能做什么(优点)
代码复用、方法覆写、多态
4.3.怎么用
语法: class 类名 extends 父类名{}
class B extends A{}
5.Super
5.1.是什么
super保存了父类特征,可以理解为父类引用对象(与this类似)
用于在子类中表示父类
5.2.能做什么
- 在子类成员方法/构造方法中,用于区分与子类同名的成员变量 super.xxx
- 在子类构造方法中,super(…)调用父类的构造方法,必须在子类构造方法第一行
- 如果子类构造方法中没有显示出现this()和super()的话,默认第一行有super()调用父类无参构造(若无extends则默认继承java.lang.Object类)
- this()和super()不能同时出现在构造方法中
5.3.怎么用
5.3.1.区分父类和子类同名的属性
//子类
System.out.println("子类年龄:"+age);
System.out.println("子类年龄:"+this.age);
//父类
System.out.println("父类年龄:"+super.age);
5.3.2.调用父类的构造方法
public Sub(){
//super()默认就有,所以一般不需要写
//如果要写,一定是调用父类的有参构造
super();
System.out.println("子类构造方法");
}
5.4.注意
构造方法私有化后不能被继承
因为子类构造方法中会调用父类的构造方法
由于父类进行了私有化,子类无法访问,所以会导致报错
6.覆写/重写
6.1.是什么
对继承的方法进行重新编写
6.2.应用场景
当父类无法满足子类需求的时候,子类需要根据自己的需求进行功能重写
重写的要求:
- 必须在有继承关系的体系中
- 方法名必须相同,返回值,参数列表 都必须相同
- 重写的方法不能比原方法有更低的访问权限
- 不能比原方法有更广泛的异常
- 覆写特指成员方法,只有成员方法可以覆写
重写的目的:
- 为了满足需求
- 错误越来越少
- 访问权限越来越广
class Animal{
public void eat(){
System.out.println("动物吃东西");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
6.3.@Override
class Dog extends Animal{
//@override注解,源码注解,生成class文件后就被删除了
//该注解只是一种检查机制,当编译时,会检察该方法是否符合方法腹泻的要求
//如果不符合方法覆写,则会提醒报错,所以该注解是一种检查机制
//防止程序员因粗心而导致的错误
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}