本文主要是介绍八、面向对象编程(高级),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 一、类变量与类方法
- 1.1 类变量快速入门
- 1.2 什么是类变量
- 1.3 类变量使用注意事项和细节讨论
- 1.4 类方法基本介绍
- 1.5 类方法使用场景
- 1.6 类方法的注意事项和细节讨论
- 二、理解main方法 static
- 三、代码块
- 3.1 基本介绍
- 3.2 代码块使用注意事项和细节讨论
- 四、单例模式
- 五、final关键字
- 5.1 final的基本介绍
- 5.2 final使用注意事项和细节讨论
- 六、抽象类
- 6.1 抽象类的引入
- 6.2 抽象类基本介绍
- 6.3 抽象类的最佳实践
- 七、接口
- 7.1 接口的引入
- 7.2 接口的基本介绍
- 7.3 接口的深度讨论
- 7.4 接口的注意事项和细节
- 7.5 实现接口 vs 继承类
- 7.5 接口的多态特性
- 八、内部类
- 8.1 内部类基本介绍
- 8.2 局部内部类
- 8.3 匿名内部类
- 8.3.1 匿名内部类的使用注意事项
- 8.3.2 匿名内部类的最佳实践
- 8.4 成员内部类
- 8.5 静态内部类
- 九、细节
- 9.1 static变量
- 9.2 类变量与类方法
- 9.3 类成员的初始化与实例对象成员的初始化
- 9.4 接口在JDK 8 后的特性
一、类变量与类方法
1.1 类变量快速入门
class Child{private String name;// 定义一个变量count,是一个类变量(静态变量)static 静态// 改变量最大的特点就是会被Child类的所有对象实例访问public static int count = 0;public Child(String name){this.name = name;}public void join(){System.out.print(name + "加入了游戏");}
}
-
注意:JDK1.8之前,静态变量在方法区中的
静态域
中;JDK1.8及之后,静态域存储于定义类型的Class对象
中,Class对象
如同堆中其他对象
一样,存在于GC堆中 -
记住一点:static变量是对象共享的,不管 static 变量在哪里,共识 (1) static 变量被同一个类所有对象共享 (2) static类变量,在类加载的时候就生成了
1.2 什么是类变量
类变量
是随着类的加载而创建的,所以即使没有创建对象实例也可以通过类访问
package com.codeblock;public class CodeBlockDetail01 {public static void main(String[] args) {// AA被加载时,按顺序初始化类变量(n2 --> n1)// out: 1. getN1被执行(初始化时的打印) 2. 200(调用类变量的返回)System.out.println(AA.n2); }
}class AA{public static int n2 = 200;public static int n1 = getN1();public static int getN1(){System.out.println("getN1被执行");return 100;}}
1.3 类变量使用注意事项和细节讨论
1.4 类方法基本介绍
1.5 类方法使用场景
1.6 类方法的注意事项和细节讨论
二、理解main方法 static
三、代码块
3.1 基本介绍
代码块
仅用于加载类
或创建对象
3.2 代码块使用注意事项和细节讨论
package com.codeblock;public class CodeBlockDetail01 {public static void main(String[] args) {AA a = new AA(); // 执行静态代码块的内容AA aa = new AA(); // 由于AA类已被加载,则不会执行静态代码块中的内容}
}class AA{// 静态代码块static{System.out.println("AA的静态代码块1");}}
public class CodeBlickDetail2{public static void main(String[] args){// 类变量的显示初始化 与 静态代码块中的内容按顺序执行// 属性的显示初始化 与 成员代码块中的内容按顺序执行A a = new A(); // 1. getN1被执行... 2. 静态代码块被执行... 3. getN2被执行... 4. 普通代码块被执行...}
}class A{private int n2 = getN2();{System.out.println("普通代码块被执行...");}public static int n1 = getN1();static{System.out.println("静态代码块被执行...");}public static int getN1(){System.out.println("getN1被执行...");return 100;}public static int getN2(){System.out.println("getN2被执行...");return 200;
}}
class A{public A(){ // 构造器// 这里隐藏的执行要求// (1) super();// (2) 代用普通代码块与属性初始化System.out.println("ok");}
}
package com.codeblock;public class CodeBlockDetail01 {public static void main(String[] args) {new BB();}
}class AA{public int aa02 = getAa02();{System.out.println("AA code block 执行..."); // (6)}public int getAa02(){System.out.println("getAa02执行..."); // (5)return 200;}public static int aa01 = getAa01();static {System.out.println("AA static code block 执行..."); // (2)}public static int getAa01() {System.out.println("getAa01执行..."); // (1)return 1;}public AA(){// 调用Object的构造器(略)// 执行 代码块 与 属性初始化System.out.println("AA 的构造器"); // (7)}}class BB extends AA{public int bb02 = getBb02();{System.out.println("BB code block 执行..."); // (9)}public int getBb02(){System.out.println("getBb02执行..."); // (8)return 100;}static {System.out.println("BB static code block 执行..."); // (3)}public static int bb01 = getBb01();public static int getBb01() {System.out.println("getBb01执行..."); // (4)return 10;}public BB(){// 调用AA的构造器// 执行 代码块 与 属性初始化System.out.println("BB 的构造器"); // (10)}}
四、单例模式
- 什么是单例模式
五、final关键字
5.1 final的基本介绍
5.2 final使用注意事项和细节讨论
- 注意如果对方法的形式参数使用
final
,则在方法内部不能对该形参变量重新赋值;但是,如果是引用类型的形参变量被加了final
,是可以对其属性进行修改的 (本质是该局部变量的值一直都是引用变量的地址)
六、抽象类
6.1 抽象类的引入
abstract class Animal{public String name;public int age;public Animal(String name, int age){this.name = name;this.age = age;}// 这里 eat 实现了,其实也没有什么意义// 即:父类方法不确定性的问题// ====> 考虑将该方法设计为抽象(abstract)方法// ====> 所谓抽象方法就是没有实现的方法// ====> 所谓没有实现就是指,没有方法体// ====> 当一个类中存在抽象方法时,需要将该类声明为 abstract 类// public void eat(){// System.out.println();// }public abstract void eat();}
6.2 抽象类基本介绍
- 抽象类使用的注意事项和细节讨论
// 对于上述第7点
abstract class E{public abstract void hi();
}// 继承抽象类的,第一种情况:可以不对抽象方法进行实现
abstract class F extends E{}// 继承抽象类的,第二种情况
abstract class G extends E{public abstract void hi(){ // 重写了抽象类的方法}
}
注意:Java中类方法不能被重写,而 抽象方法
存在的意义就是被子类重写
6.3 抽象类的最佳实践
七、接口
7.1 接口的引入
7.2 接口的基本介绍
package com.interface_;public class TestInterface {}interface Interface{// 属性强制是 public static final 修饰,可以不写// 方法(除默认方法)强制是 public abstract 修饰,可以不写// 默认方法是 public 修饰的// 写属性,默认是 public static final 可以省略不写public static final String str = "Hello";// 写方法// 在接口中,抽象方法,可以省略abstract关键字 和 public修饰符void hi();// 在jdk1.8后,可以有默认实现方法,需要使用 default关键字修饰default void ok(){System.out.println("ok ....");}// 在jdk1.8后,可以有静态方法static void test1(){}}
7.3 接口的深度讨论
7.4 接口的注意事项和细节
- 注:
接口
之间是继承(支持多继承),类
和接口
之间是实现。
7.5 实现接口 vs 继承类
- 注:
接口
是对java单继承
的扩展。当子类继承了父类,就自动的拥有父类的功能。如果子类需要扩展功能,可以通过实现接口的方式扩展 - 更通俗的理解,
继承
主要使子类中拥有父类的方法,侧重于复用性
;接口实现
主要使类中实现
接口的抽象方法
侧重于重写
7.5 接口的多态特性
// 接口多态传递现象
public class InterfacePolyPass{public static void main(String[] args){IG ig = new Teacher(); // 接口引用可以指向IH ih = new Teacher(); // 接口多态传递}interface IH{}
interface IG extends IH{} // 继承了 IH 接口
class Teacher implements IG{}
}
八、内部类
8.1 内部类基本介绍
- 类的五大属性:
属性
、方法
、构造器
、代码块
、内部类
8.2 局部内部类
- 在
方法体
或代码块
中定义的类
(常见的是在方法体中定义类)
package com.innerclass;public class InnerTest {public static void main(String[] args) {Outer o = new Outer();System.out.println(o.f1());}
}class Outer {private int n1 = 1;public int f1() {class Inner { // 方法中的局部内部类private int n1 = 1; // 与外部类的属性重名private int n2 = 2;public int getN2() {return this.n2;}public void test() {// 需要访问外部类的属性(与内部类中属性重名)// Outer.this 的本质就是外部类的对象,即哪个对象调用了f1, Outer.this 就是哪个对象System.out.println(Outer.this.n1);}}Inner inner = new Inner();inner.test();return inner.getN2();}}
8.3 匿名内部类
package com.innerclass;public class InnerAnonyClass {public static void main(String[] args) {Outer04 o = new Outer04();o.method();}
}class Outer04 { // 外部类private int n1 = 10;public void method() {// 基于接口的匿名内部类// 解读// 1. 需求:想使用IA接口,并创建对象// 2. 传统方式,是写一个类,实现该接口,并创建对象// 3. 老韩需求是 Tiger 类只是使用一次,后面再不使用// 4. 可以使用匿名内部类来简化开发// 5. tiger 的编译类型? IA// 6. tiger 的运行类型? 就是匿名内部类 Outer04$1/*底层 会分配 类名 Outer04&1class Outer04$1 implements IA {@Overridepublic void call() {System.out.println("老虎叫唤...");}}*/// 7. jdk底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1 实例,并且把地址// 放回 tiger// 8. 匿名内部类只能使用一次,就不能再使用(指的是该类的实例被加载进堆后,其类信息就被释放掉)IA tiger = new IA() {@Overridepublic void call() {System.out.println("老虎叫唤...");}};tiger.call();// 演示基于类的匿名内部类// 分析// 1. father的编译类型? Father// 2. father的运行类型? Outer04$2// 3. 底层会创建匿名内部类/*class Outer04$2 extends Father {@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}}*/// 4. 同时也直接返回了 匿名内部类 outer04$2的对象// 5. 注意 ("jack") 参数列表会传递给 构造器Father father = new Father("jack") {@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}};father.test();// 基于抽象类的匿名内部类Animal animal = new Animal() {@Overridepublic void eat() {System.out.println("小狗吃骨头...");}};animal.eat();}
}interface IA {void call();}class Father {private String name;public Father() {}public Father(String name) {this.name = name;}public void test() {System.out.println("test...");}public void setName(String name) {this.name = name;}public String getName() {return name;}
}abstract class Animal {public abstract void eat();
}
8.3.1 匿名内部类的使用注意事项
8.3.2 匿名内部类的最佳实践
8.4 成员内部类
8.5 静态内部类
九、细节
9.1 static变量
-
注意:JDK1.8之前,静态变量在方法区中的
静态域
中;JDK1.8及之后,静态域存储于定义类型的Class对象
中,Class对象
如同堆中其他对象
一样,存在于GC堆中 -
记住一点:static变量是对象共享的,不管 static 变量在哪里,共识 (1) static 变量被同一个类所有对象共享 (2) static类变量,在类加载的时候就生成了
9.2 类变量与类方法
子类
是不继承父类的static变量和方法
的。因为这是属于类本身的。但是子类是可以访问的。子类
和父类
中同名的static变量和方法
都是相互独立的,并不存在任何的重写的关系。- 在多态的情况下调用
类变量
与类方法
均看均由编译类型
类方法
可以在同一类重载
public class Test{public static void main(String args){Base sub = new Sub();System.out.print(sub.n); // 1System.out.print(sub.getNum()); // 1Sub s = new Sub();System.out.print(s.n); // 2System.out.print(s.getNum()); // 2}}class Base{public static int n = 1;public static int getNum(){return 1;}
}class Sub{public static int n = 2;public static int getNum(){return 2;}}
9.3 类成员的初始化与实例对象成员的初始化
- 类成员:类变量、类方法
- 类变量:
- 可以显示赋值
public static String str = "1"
- 在
static 代码块
中
- 可以显示赋值
- 类方法:在随类的加载而被加载进方法区
- 类变量:
- 实例对象成员:属性和方法
- 属性:
- 可以显示赋值
- 在代码块中
- 在构造器中
- 属性:
9.4 接口在JDK 8 后的特性
package com.interface_;public class TestInterface {}interface Interface{// 属性强制是 public static final 修饰,可以不写// 方法(除默认方法)强制是 public abstract 修饰,可以不写// 默认方法是 public 修饰的// 写属性,默认是 public static final 可以省略不写public static final String str = "Hello";// 写方法// 在接口中,抽象方法,可以省略abstract关键字 和 public修饰符void hi();// 在jdk1.8后,可以有默认实现方法,需要使用 default关键字修饰default void ok(){System.out.println("ok ....");}// 在jdk1.8后,可以有静态方法static void test1(){}}
这篇关于八、面向对象编程(高级)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!