面向对象的进阶
1.类变量
// 类变量:叫做静态变量/静态属性 ,是该类所有的对象共享的变量,任何一个该类的对象去访问它得到的都是相同的值
// 定义语法: 访问修饰符 + static + 数据类型 + 变量名
//如何访问 1.类名.变量名 (最好用这个,比较规范) // 在类加载的时候 静态变量就已经被加载好了
// 2.对象名.变量名
// 使用细节
//1.当一个类中所有对象共享一个变量的时候,使用静态变量
//2.加上static是静态变量 不加是实例变量/普同变量/非静态变量
//3.做静态变量/静态属性 ,是该类所有的对象共享的变量,实例变量是每个对象独享的
//4.//如何访问 1.类名.变量名
// 2.对象名.变量名
//5.实例变量不能通过类名.变量名去访问 需要创建对象 对象名.变量名
//6.在类加载的时候 静态变量就已经被加载好了,即使不创建对象,只要类加载就可以使用类变量
//7.类的生命周期是随类的加载开始,随类消亡
// 内存分析
//1.在栈中 生成child1 -> 指向 堆中的地址 就是该对象的地址 之后在指向方法区 获取信息
//2.同时共享堆中的静态变量
//实例讲解
Child child1 = new Child("奶盖");
child1.join();
// count++;
Child child2 = new Child("酷盖");
child2.join();
// count++;
Child child3 = new Child("盖");
child3.join();
// count++;
System.out.println("共有" + Child.count);
class Child{
private String name;
public static int count = 0; //该变量最大的特点是会被Child的所有对像实现共享
//1.static 同一个类的所有对象共享
//2.static 在类加载的时候就加载好了
public Child() {
}
public Child(String name) {
this.name = name;
}
public void join(){
count++;
System.out.println(name + " 加入");
}
2.类方法
// 类方法
// 语法: 访问修饰符 + static + 数据返回类型 方法名(){}
// 调用: 类名。类方法名 或者 对象名。类方法名
// 好处 方便调用
// 使用细节
//1.类方法和普通方法都是随类的加载而加载,将结构信息存储到方法区里面 类方法无this的参数 普通方法中隐含着this的参数
//2.调用: 类名。类方法名 或者 对象名。类方法名
//3.类方法中不允许使用和对象有关的关键字 this super 普通方法可以
//4.(重点) 静态方法只能访问静态变量和静态方法 普通方法既可以访问静态变量 静态方法 也可以访问普通变量 普通方法NM
3.代码块
// 代码块
//好处
//1.相当于另外一种形式的构造器(对构造器的补充机制) 可以进行初始化操作
//2.场景 多个构造器都有重复语句,可以抽取到初始代码块中,提高代码重复性
//使用细节
//1.static代码块 ,作用对类进行初始化 ,随类的加载而执行,并且只能执行一次,每创建一个对象就执行一次
//2.类在什么时候加载 重点
1).创建对象实例时,(new)
2).创建子类对象实例,父类也会被加载 // 会调用父类的构造器
3).使用类的静态成员时,(静态属性 静态方法)
//3.普通代码块只有创建新的对象才会被调用
//4. 创建一个对象时,在一个类的调用顺序 重点 难点
1)调用静态代码块和静态属性初始化
(静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和静态属性初始化按顺序调用)
2)调用普通代码块和普通属性初始化
(普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和普通属性初始化按顺序调用)
3)调用构造方法(如果有父类,会先执行父类的普通代码块 构造器 在执行子类的普通代码块 构造器)
//5.构造器的前面隐含了super() 和 调用普通代码块 但是父类优先于子类
//6.创建子类的对象时(继承关系) 静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法使用顺序
1.父类的 静态代码块,静态属性初始化(优先级一样,按定义的顺序)
2.子类的 静态代码块,静态属性初始化(优先级一样,按定义的顺序)
3..父类的 普通代码块,普通属性初始化(优先级一样,按定义的顺序)
4.父类的构造方法
5.子类的 普通代码块,普通属性初始化(优先级一样,按定义的顺序)
6.子类的构造方法
//代码块调用顺序的实例讲解
class teacher{
{
System.out.println("父类的普通代码块"); //5.
}
public static int n1 = getN1();
public teacher() {
System.out.println("父类的无参构造器"); //6.
}
static {
System.out.println("父类的静态属性代码块"); //2.
}
public static int getN1(){
System.out.println("老师教学的静态方法"); //1.
return 100;
}
}
class Stu extends teacher{
public Stu() {
System.out.println("子类的无参构造器"); //8.
}
public Stu(String name) {
System.out.println("子类的有参构造器");
}
{
System.out.println("子类的普通代码块"); //7.
}
private static int n2 = s();
static {
System.out.println("子类的静态代码块"); //4.
}
public static int s(){
System.out.println("学生的静态学习方法"); //3.
return 2;
}
public int s1(){
System.out.println("学生的普通方法");
return 1;
}
}
// final的使用细节
//1.final修饰的属性也叫常量 一般 XX XX XX_XX 定义
//2.final修饰的属性在定义的时候,必须赋初始值 赋值的位置有
//1)定义的时候
//2)构造器中
//3)代码块中
//3.finaL修饰的属性如果是静态的,则初始化的地方只能是 定义时,在静态代码块 可以,构造器里面不能赋值
//4. final类不能继承,但可以实例化对象
//5.如果类不是final类,但是含有final 的方法 ,虽然不能重写但是可以继承
//6.如果一个类已经是final类,就没有必要再将方法修饰成final方法了
//7.final不能修饰构造器
//8.final 和static 往往搭配使用,效率更高 ,不会导致类的加载(进而 不会调用静态代码块)—,底层编译器做了优化处理
//9.包装类 String Boolean不能被继承
4.接口
// 接口介绍 :对一些不明确的方法进行封装到一起,之后在类中重写接口的方法
就是给出一些没有实现的方法,封装到一起,到某个类使用的时候,根据具体情况把方法写出来
// interface 接口名{ 属性 方法}
// class 类名 implement 接口 {自己的属性 自己的方法 必须实现的接口的抽象方法}
//接口的使用细节
//1.接口不能实例化
//2.接口中的方法是 public 方法 接口中的抽象方法不用抽象修饰符修饰
//3.一个普通类实现接口,就必须将接口的所有方法实现
//4.抽象类实现接口,可以不用实现接口的方法
//5.一个类可以同时访问多个接口
//6.接口的属性只能是final 而且是public static final 修饰的 int a = 1; == public static final;
//7.接口的访问形式 接口名.属性名
//8.接口不能继承其他类,但是可以继承多个接口 interface A extends B,C{}
//9.接口的修饰符只能是 public 和默认 这点和类的修饰符一样
// 好处: 便于统一管理 统一方法名 便于调用 对继承的继承模式的补充
// 接口 Vs 继承like
//1.接口更加灵活,继承必须满足is-a的关系 like-a的关系
// 接口 VS 继承类
// 继承的价值主要在于: 解决代码的复用性和可维护性
// 接口的价值体现在: 设计,设计好各种规范(方法),让其它类实现这些方法,即更加灵活
// 接口比继承更加灵活
// 继承需要满足 is -a的关系 接口只需要满足like-a的关系
// 接口在一定情况再实现了代码的解耦(接口规范性 +动态绑定)
// 接口多态传递
IG ig = new N();
IH ih = new N();
//如果IG继承了IH的接口,而N类实现了对IG的接口 那么也就说明N 也玩成了IH的接口 这就是接口的多态传递
}
interface IH{
}
interface IG extends IH{
}
class N implements IG{
}
// 目前 类的五大成员已完成 成员方法 成员变量 构造器 代码块 还有内部类没学
//接口的实例讲解
public static void main(String [] args){
littleMonkey littleMonkey = new littleMonkey("齐天大圣");
littleMonkey.climb();
littleMonkey.swim();
littleMonkey.fly();
}
}
class Monkey{
private String name;
public Monkey() {
}
public Monkey(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void climb(){
System.out.println( name + "会爬树");
}
}
interface FishAbility{
public void swim();
}
interface BirdAbility{
public void fly();
}
class littleMonkey extends Monkey implements FishAbility,BirdAbility{
public littleMonkey() {
}
public littleMonkey(String name) {
super(name);
}
@Override
public void climb() {
super.climb();
}
@Override
public void swim() {
System.out.println(getName()+"会游泳");
}
@Override
public void fly() {
System.out.println(getName() + "会上天");
}
}
5.抽象类
// 抽象类
//当父类的某些方法不确定的时候,用abstract来修饰
// 使用方法
//1.抽象方法就是没有实现的方法
//2.所以抽象方法没有方法体
//3.当一个类中存在抽象方法,该类要声明为抽象类
//4.一般,抽象类会被继承,由子类完成抽象方法
// 使用细节
//1.抽象类不能实例化
// A a = new A(); 1.抽象类不能实例化
//2.抽象类 不一定需要包含Abstract方法
//3.一旦类中有抽象方法,类必须修饰为抽象类
//4.Abstract不能修饰属性和其他 只能修饰类和方法
//5.抽象类可以有任何成员(本质还是类) 如 非抽象方法 构造器 静态属性 静态方法
//6.抽象方法不能有主体
//7.如果一个类继承了抽象类必须实现抽象类的抽象方法,除非他也声明为抽象类
//8.抽象方法不能使用private final static 因为这些关键字和重写违背
实例讲解
/ 抽象类的模板设计模式
//提高了代码复用性
public class AbstractHomeWork01 {
public static void main(String [] args){
cal cal = new cal();
cal.time();
}
}
abstract class Template{
public abstract void job();
public void time(){
long start = System.currentTimeMillis(); //二 得到当前的时间
job();
long end = System.currentTimeMillis();
System.out.println("执行的时间" + (end - start) );
}
}
class cal extends Template{
// public void Time(){
// long start = System.currentTimeMillis(); //二 得到当前的时间
//
// job();
//
// long end = System.currentTimeMillis();
// System.out.println("执行的时间" + (end - start) );
//
// }
public void job(){
// long start = System.currentTimeMillis(); //一 得到当前的时间
long num = 0;
for (long i = 0; i < 88800000; i++) {
num += i;
}
// long end = System.currentTimeMillis();
// System.out.println("执行的时间" + (end - start) +" " + "i =" + num);
}
}