封装、继承、多态及抽象是面向编程的四大特性。
1)类的静态模块(除了构造器,其是特殊的静态方法)先加载执行,且父类的静态模块先与子类的静态模块加载。
2)非静态模块(实例变量初始化、非静态代码块)会先于构造器执行。父类实例化完成后,子类才会进行实例化。
问:为啥父类的静态模块先与子类的静态模块执行?
- public class InitOrder {
-
- public static void main(String[] args) {
- new Son();
- /**
- * Father 静态模块,staticNum = 2
- * Son 静态模块,staticStr = Hello
- * father 实例模块, num = 9
- * Father 构造器
- * son 实例模块,str = Init
- * Son 构造器
- */
- }
-
- private static class Father {
- static int staticNum = 2;
- int num = 9;
-
- static {
- System.out.println("Father 静态模块,staticNum = " + staticNum);
- }
-
- {
- System.out.println("father 实例模块, num =" + num);
- }
-
- public Father() {
- System.out.println("Father 构造器");
- }
- }
-
- private static class Son extends Father {
-
- static String staticStr = "Hello";
- String str = "Init";
-
- static {
- System.out.println("Son 静态模块,staticStr = " + staticStr);
- }
-
- {
- System.out.println("son 实例模块,str = " + str);
- }
-
- public Son() {
- System.out.println("Son 构造器");
- }
- }
-
- }
1)“缺陷”:私有方法不会有多态行为
2)构造器内部的多态行为:在父类的构造器中如果使用this来调用实例方法(且该方法被子类重新),那么此时会有多态行为,即真正执行的是子类的方法。
- public class Polymorphic {
-
- public static void main(String[] args) {
- Father father = new Son();
- /**
- * Father 构造器
- * father.fun1()
- * son.fun2()
- * Son 构造器
- */
- }
-
- private static class Father {
-
- public Father() {
- System.out.println("Father 构造器");
- fun1();
- fun2();
- }
-
- private void fun1() {
- System.out.println("father.fun1()");
- }
-
- public void fun2() {
- System.out.println("father.fun2()");
- }
-
- }
-
- private static class Son extends Father{
-
- public Son() {
- System.out.println("Son 构造器");
- }
-
- private void fun1() {
- System.out.println("son.fun1()");
- }
-
- @Override
- public void fun2() {
- System.out.println("son.fun2()");
- }
- }
-
- }
2)继承的子接口可以重复定义方法,但是如果只是返回值不同,而其他签名相同,则会编译报错。
1)内部类与迭代器。
像List、Set 等容器中,它们的主要职责是存储数据。但是好多时候我们需要遍历这些数据。 根据“单一职责”的要求,我们把存储与遍历这两个不同的职责写入到两个类中。
而我们常常会把迭代器写为容器的内部类,这样方便迭代器访问其数据。
- public class CustomInnerIterator {
-
- public static void main(String[] args) {
- CustomList<Integer> customList = new CustomList<>();
- for (int i = 0; i < 15; i++) customList.addItem(i);
- Iterator<Integer> iterator = customList.createIterator();
- while (iterator.hasNext()) System.out.println(iterator.next());
-
- }
-
- private interface Iterator<T> {
- boolean hasNext();
- T next();
- T current();
- }
-
- private static class CustomList<T> {
-
- private final int INIT_SIZE = 10;
- private Object[] dataArray;
- private int size = 0;
-
- public CustomList() {
- dataArray = new Object[INIT_SIZE];
- }
-
- private void grow() {
- if (size > dataArray.length / 2) {
- dataArray = Arrays.copyOf(dataArray, dataArray.length + INIT_SIZE);
- }
- }
-
- public void addItem(T elemnt) {
- grow();
- dataArray[size++] = elemnt;
- }
-
- public Iterator<T> createIterator() {
- return new CustomIterator();
- }
-
- public class CustomIterator implements Iterator<T> {
-
- int pos = 0;
-
- @Override
- public boolean hasNext() {
- return size > pos;
- }
-
- @Override
- public T next() {
- return (T)dataArray[pos++];
- }
-
- @Override
- public T current() {
- return (T)dataArray[pos];
- }
- }
- }
-
- }
2)普通内部类不能有静态模块。
普通内部类(非静态内部类)与外部类的对象紧密相关,普通内部类实例的生命依附于外部类的实例。 而静态模块是类级别的,在普通内部类定义静态模块没有任何意义。
3)局部内部类与匿名内部类的区别:局部内部类可以使用构造器。
- public class LocalAndAnonymity {
-
- public static void main(String[] args) {
- Interface interface1 = createInterface1("可以使用构造器哦");
- Interface interface2 = createInterface2();
- interface1.fun("interface1");
- interface2.fun("interface2");
- }
-
- private interface Interface {
- void fun(String str);
- }
-
- private static Interface createInterface1(String info) {
- class InterfaceImpl implements Interface {
-
- private final String otherInfo;
-
- public InterfaceImpl(String otherInfo) {
- System.out.println("局部内部类的构造器");
- // 构造器,可以构造器传参等
- this.otherInfo = otherInfo;
- }
-
- @Override
- public void fun(String str) {
- System.out.println("局部内部类:" + otherInfo + "-" + str);
- }
- }
- return new InterfaceImpl(info);
- }
-
- private static Interface createInterface2() {
- return new Interface() {
- @Override
- public void fun(String str) {
- System.out.println("匿名内部类:" + str);
- }
- };
- }
-
- }