Java学习笔记08
工具类中使用静态
- 在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实是一样的
 - 方法改进为静态后,就可以直接通过类名调用
 - 把构造方法私有化,外界就不能再创建对象了
 - 示例代码
 
public class ArrayTool {
    //将构造方法私有化,外界就不能再创建对象了
    private ArrayTool() {
        // TODO 自动生成的构造函数存根
    }
    public static void printArray(int[] arr) {
        for(int x = 0;x < arr.length;x++) {
            if(x == arr.length -1) {
                System.out.println(arr[x]);
            
            }else {
                System.out.println(arr[x] + "---");
            }
        }
    }
}
说明书的制作
- 如何制作一个说明书
 
- 写一个工具类
 - 对这个类加入文档注释
示例代码 
/*
 * 这是针对数组进行操作的工具类
 * @author lhk
 * @version V1.0
 */
public class ArrayTool {
    //将构造方法私有化,外界就不能再创建对象了
    /**
     * 这是私有构造
     */
    private ArrayTool() {
        // TODO 自动生成的构造函数存根
    }
    
    /*
     * 这是遍历数组的方法
     * @param arr 这是要被遍历的数组
     */
    public static void printArray(int[] arr) {
        for(int x = 0;x < arr.length;x++) {
            if(x == arr.length -1) {
                System.out.println(arr[x]);
            
            }else {
                System.out.println(arr[x] + "---");
            }
        }
    }
    /*
     * 这是获取数组中最大值的方法
     * @param arr 这是获取最大值的数组
     * @return int 返回数组中的最大值
     */
    public static int getMax(int[] arr) {
        int m = arr[0];
        for(int x = 1;x < arr.length;x++) {
            if(arr[x] > m) {
                m = arr[x];
            }
        }
        return m;
    }
}
- 用工具解析文档注释
javadoc工具 - 格式
javadoc -d 目录 -author -version ArrayTool.java
目录:就可以写一个文件夹的路径 
如何使用帮助文档
- 打开帮助文档
 - 点击显示,找到索引,看到输入框
 - 知道你要找谁?以Scanner举例
 - 在输入框里面输入Scanner,然后回车
 - 看包
java.lang包下的类不需要导入,其他的全部需要导入
要导入:
java.util.Scanner - 再简单的看看类的解释和说明,别忘了看看该类的版本
 - 看类的结构
成员变量,字段摘要
构造方法 ,构造方法摘要
成员方法 ,方法摘要 - 学习构造方法
A:有构造方法 就创建对象
B:没有构造方法 成员可能都是静态的,所以都是随着类的加载而存在,不会随着对象的创建而创建,所以不需要构造方法。 - 看成员方法
A:左边
是否静态:如果静态,可以通过类名调用
返回值类型:人家返回什么,你就用什么接收
B:右边
看方法名:方法名称不要写错
参数列表:人家要什么,你就给什么;人家要几个,你就给几个 
代码块的概述和分类
- 局部代码块
 
- 处于局部位置,用于限定变量的生命周期
 
- 构造代码块
 
- 在类中的成员位置,用{}括起来的代码,每次调用方法执行前,都会先执行构造代码块
 - 作用:可以把多个构造方法中的共同代码放在一起,对对象进行初始化
 
- 静态代码块
 
- 在类中的成员位置,用{}括起来的代码,只不过它用static 修饰了
 - 作用:一般是对类进行初始化
 
- Attension
 
- 它们的执行顺序为:
静态代码块---构造代码块---构造方法
静态代码块:只执行一次
构造代码块:每次调用构造方法都执行 
- 示例代码
 
class Code {
    //静态代码块
    static{
        int a = 104;
        System.out.println(a);
    }
    //构造代码块
    {
        int x = 1024;
        System.out.println(x);
    }
    
    public Code() {
        System.out.println("code");
    }
    
    {
        int x = 102;
        System.out.println(x);
    }
}
public class CodeDemo {
    public static void main(String[] args) {
        //局部代码块,用于限定变量的生命周期
        {
        int x = 10;
        System.out.println(x);
        }
        System.out.println("-------");
        Code c = new Code();
        System.out.println("-------");
        Code c2 = new Code();
    }
}
继承的引入
- 我们把多个类中相同的内容定义到一个独立的类中,然后让这多个类和这个独立的类产生一个关系,有了这个关系后,这多个类可以具备这个独立的类的功能,为了实现这个效果,Java 就提供了一个技术:继承
 - 代码示例
 
//继承格式如下
class Fu{
    String name;
    int age;
    public Fu() {
    }
    public void eat() {
        System.out.println("lhk");
    }
}
class Zi extends FU {
    public Zi() {
    }
}
- 继承的好处
 
- 提高代码的复用性
 - 提高代码的维护性
 - 让类与类之间产生了关系,是多态的前提(这也是一个弊端,因为类的耦合性增强了)
 
开发的原则:低耦合,高聚合。
耦合:类与类的关系
内聚:就是自己完成某件事的能力
Java中类的继承特点
- Java 只支持单继承,不支持多继承
 - Java 支持多层继承(继承体系)
 - 代码示例
 
class G {
    public void show() {
        System.out.println("lhk");
    }
}
class F extends G {
    public void method() {
        System.out.println("ppn");
    }
}
class S extends F {
    
}
public class ExtendsDemo {
    public static void main(String[] args) {
        S s = new S();
        s.method();
        s.show();
    }
}
继承的注意事项
- 子类只能继承父类中所有非私有成员(成员方法和成员变量)
 - 子类不能继承父类的构造方法,但是可以通过super(后面学)关键字去访问父类构造方法
 - 不要为了部分功能而去继承
 
this 和 super 的区别和应用
- this 代表对本类的引用
 - super 代表父类存储空间的标识(理解为父类的引用,可以操作父类的成员)
 - 使用:
 
- 调用构造方法
 
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
- 代码示例
 
class F2 {
    public int num = 10;    
}
class S2 extends F2 {
    public int num = 20;
    
    public void show() {
        int num = 30;
        System.out.println(num);
        System.out.println(this.num);
        System.out.println(super.num);
    }
}
public class ExtendsDemo2 {
    public static void main(String[] args) {
        S2 s = new S2();
        s.show();
    }
}
继承中构造方法的关系
- 子类中所有的构造方法默认都会访问父类中空参数的构造方法
 
原因:因为子类会继承父类中的数据,可能还会使用父类中的数据,所以子类初始化之前,一定要先完成父类数据的初始化
注意:子类每一个构造方法的第一条语句默认都是:super();
- 代码示例
 
class F3 {
    public F3() {
        System.out.println("F3的无参构造方法");
    }
    
    public F3(String name) {
        System.out.println("F3有参");
    }
}
class S3 extends F3 {
    public S3() {
        System.out.println("S3的无参构造方法");
    }
    
    public S3(String name) {
        System.out.println("S3有参");
    }
}
public class superDemo {
    public static void main(String[] args) {
        S3 s = new S3();
        System.out.println("------");
        S3 s2 = new S3("lhk");
        
    }
}
继承中构造方法的注意事项
- 如果父类中没有无参构造方法,那么自己的构造方法会出现什么呢?又该如何解决?
 
- 在父类中加一个无参构造方法
 - 通过super关键字去显示调用父类的带参构造方法
 - 子类通过this关键字去调用本类的其他构造方法(子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化)
 - 注意:this和super的使用必须出现在第一条语句上,如果不是放在第一条语句上,就可能对父类数据多次初始化引起报错
 - 代码示例
 
class F4 {
    //public F4() {
        
    //}
    public F4(String name) {
        System.out.println("F4带参构造");
    }
}
class S4 extends F4 {
    public S4() {
        super("lhk");
        System.out.println("S4的无参构造");
    }
    
    public S4(String name) {
        //super("lhk");
        this();
        System.out.println("S4的有参构造");
    }
}
public class ExtendDemo3 {
    public static void main(String[] args) {
        S4 s = new S4();
        System.out.println("------");
        S4 ss  = new S4("lhk");
    }
}
继承中的面试题2
- 静态的内容是随着类的加载而加载
 - 静态代码块的内容会优先执行
 - 子类初始化之前会先进行父类的初始化
 - 代码示例:
 
class F5 {
    static {
        System.out.println("lhk");
    }
    
    {
        System.out.println("ppn");
    }
    
    public F5() {
        System.out.println("jjj");
    }
}
class S5 extends F5{
    static {
        System.out.println("hsf");
    }
    
    {
        System.out.println("al");
    }
    
    public S5() {
        System.out.println("qjx");
    }
}
public class ExtendDemo4 {
    public static void main(String[] args) {
        S5 s = new S5();
    }
}
继承中的面试题3
- 一个类的初始化过程
 
- 成员变量的初始化
默认初始化
显示初始化
构造方法初始化 
- 子父类的初始化(分层初始化)
 
- 先进行父类初始化,然后进行子类初始化
 - 问题:虽然子类中的构造方法默认有一个super(),但初始化的时候,不是按照那个顺序进行的。而是按照分层初始化进行的,它仅仅表示要先初始化父类数据,再初始化子类数据。
 - 代码示例:
 
class X {
    Y b = new Y();
    X() {
        System.out.print("X");
    }
}
class Y {
    Y() {
        System.out.print("Y");
    }
}
public class Z extends X {
    Y y = new Y();
    Z() {
        //super();
        System.out.print("Z");
    }
    public static void main(String[] args) {
        new Z();
    }
}
//输出YXYZ
方法重写
- 方法重写:子类中出现了和父类中方法声明一模一样的方法
 - 方法重写的应用:当子类需要父类的功能,而功能主体子类有自己持有的内容时,可以重写父类中的方法。这样,既沿袭了父类的功能,又定义了子类特有的内容
 - 代码示例:
 
class Phone {
    public void call(String name) {
        System.out.println(name);
    }
}
class NewPhone extends Phone{
    public void call(String name) {
        //System.out.println(name);
        super.call(name);
        System.out.println("听天气预报了");
    }
    
}
public class ExtendsDemo6 {
    public static void main(String[] args) {
        NewPhone np = new NewPhone();
        np.call("lhk");
    }
}
方法重写的注意事项
- 父类中私有方法不能被重写
 
- 因为父类私有方法子类根本就无法继承
 
- 子类重写父类方法时,访问权限不能更低
 
- 最好一致
 
- 父类静态方法,子类也必须通过静态方法进行重写(其实这个算不上方法重写,至于为什么,多态中讲解)
 - 代码示例:
 
class F7 {
    //public void show() {}
    void show() {
        System.out.println("show lhk");
    }
}
class S7 extends F7 {
    //private void show() { 
    //}
    
    void show() {
        System.out.println("show ppn");
    }
}
public class ExtendsDemo7 {
    public static void main(String[] args) {
        S7 s = new S7();
        s.show();
    }
}