Java第十二课

知识点补充和扩展。

1.1 static再说明

静态属性和静态方法,非静态属性之间的关系

package staticpackage;

public class A {

    // 成员属性 static,这个属性是属于类所有的,类加载的时候会将n加载在内存中,n的值是一个全局的,(所有对象)共享的一个值;
    public static int n = 1;

    // 成员属性 非static ,这个属性是属于对象(实例)的;
    public int x = 1;

    // 非静态(对象的方法 或者称为实例方法)的方法,通过对象名.方法名(),非静态的方法中能否直接访问静态属性?
    // 可以
    public void method01() {
        n++;
        System.out.println("method01 n :" + n);

        x++;
        System.out.println("method01 x :" + x);
    }

    // 静态的方法,是属于类所有的方法,访问的时候类名.方法名来访问() ,非静态的方法中能否直接访问静态属性?
    // 可以
    public static void method02() {
        n++;
        System.out.println("method02 n :" + n);

        //这里 静态的方法去访问x
        //Cannot make a static reference to the non-static field x
        //静态的方法不能直接访问非静态的属性
        //x++;
    }

    public static void main(String[] args) {

        // 方法method01是谁的方法? 对象的方法
        A a0 = new A();
        a0.method01(); // 2
        /// 类名.方法名
        A.method02(); // ?
        // a0.method02();不推荐使用的语法

        A a11 = new A();
        a11.method01();// ?

        System.out.println("*****************");

        A a = new A();
        a.method01(); // 2

        A a1 = new A();
        a1.method01();// ?
    }

}

method01 n :2
method01 x :2
method02 n :3
method01 n :4
method01 x :2


method01 n :5
method01 x :2
method01 n :6
method01 x :2

静态方法和实例方法,调用

package staticpackage;

public class B {

    public void mehtod01() {
        System.out.println("我是实例方法method01");
    }

    public void mehtod02() {
        mehtod01();// 实例方法 调用 实例方法
        mehtod03();// 实例方法调用静态方法
        System.out.println("我是实例方法method02");
    }

    public static void mehtod03() {
        System.out.println("我是实例方法method03");
    }

    public static void mehtod04() {
        mehtod03();// 静态方法 调用 静态方法
        //Cannot make a static reference to the non-static method mehtod02() from the type B
        //mehtod02();// 静态方法 调用 实例方法 臣妾做不到了注意咯
        System.out.println("我是实例方法method04");
    }

}

静态的代码段:

package staticpackage;

public class C {

    public C() {

        System.out.println("我是无参数逇构造方法,我也很好玩~");
    }

    /**
     * 静态代码段,类加载的时候优先执行;先于构造方法方法执行;静态代码段只执行一次; 通常用来做类的初始化操作; 一个类中可以有多个静态的代码段
     */
    static {

        System.out.println("我是 static代码段1,我很好玩~");
    }

    static {

        System.out.println("我是 static代码段2,我很好玩~");
    }

    //创建对象才执行
    {
        System.out.println("我也是一个普通的代码段");
    }

    public static void main(String[] args) throws ClassNotFoundException {

        ///Class.forName("staticpackage.C");


        // 实例化C类对象
        C c1 = new C();
        C c2 = new C();
        C c3 = new C(); 

    }

}

我是 static代码段1,我很好玩~
我是 static代码段2,我很好玩~
我也是一个普通的代码段
我是无参数逇构造方法,我也很好玩~
我也是一个普通的代码段
我是无参数逇构造方法,我也很好玩~
我也是一个普通的代码段
我是无参数逇构造方法,我也很好玩~

静态代码段,普通代码段,构造的执行顺序
这里写图片描述
用在内部类中
这里写图片描述

1.2 递归调用:

方法内部,自己调用自己: 方法的自调用;

累加求和 1+2+3+…+n的值;

package day12;

public class TestMethodInvoke {

    /**
     * 累加求和 1+2+3+...+n
     * 
     * @param n 大于0正整数
     * @return  和
     */
    public int getSum(int n) { //5  4  3 2

        if (n == 1)
            return 1;

        return getSum(n - 1) + n;// getSum(4)+5  getsum(3)+4  getsum(2)+3  getSum(1)+2
    }

    public static void main(String[] args) {
        int sum = new TestMethodInvoke().getSum(5);

        System.out.println("sum :" + sum);
    }
}

递归调用的场景: 例如: 我们可以遍历我们磁盘某个目录下的所有目录和文件;
这里写图片描述
遍历磁盘widows目录下的所有文件盒目录,直到整个目录下没有子集为止;(IO)

1.2.1 课堂练习:

请使用递归调用,来完成以下题目:
1. 求N的阶乘(n<=10)
2. 求1!+2!+3!+…n!

1.3 内部类:

在一个类的内部,定义一个类,这个内部的类称为内部类;
在内部类中可以访问外部类中的成员;反之不可以;
后面会讲到GUI(swing + Listener) ,有很多的内部类;
今天: 我们希望实现一个多继承关系;但是不能用接口;某个人,会继承父亲的特征,会继承母亲的特征;

参考代码:

package innerclasspackage;

public class Father {

    public void drink() {
        System.out.println("喝点小酒,配点枇杷~");
    }

}
package innerclasspackage;

public class Mother {

    public void cook() {
        System.out.println("煮点好吃的~小鸡炖蘑菇~");
    }

}
package innerclasspackage;

/**
 * 外部的Son称为外部类(OuterClass)
 * 
 * @author Administrator
 *
 */
public class Son {

    // 在Son的内部定义两个类 (InnerClass)
    // 继承了Father
    static class Son_Father extends Father {
        // 就会继承父类的drink
    }

    // 继承了Mother
    private class Son_Mother extends Mother {
        // 就会继承父类的cook
    }

    public void drink() {
        Son_Father sf = new Son_Father();
        sf.drink();
    }

    public void cook() {
        Son_Mother sm = new Son_Mother();
        sm.cook();
        System.out.println("大自然醉鹅~串串香~锡纸虾~");
    }

}

测试类:

package innerclasspackage;

import innerclasspackage.Son.Son_Father;


public class TestSon {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        /*Son son = new Son();
        son.cook();
        son.drink();*/
        //No enclosing instance of type Son is accessible. Must qualify the allocation with an enclosing 
        //instance of type Son (e.g. x.new A() where x is an instance of Son).

        //用外部对象.new 内部类()
        /*Son son = new Son();
        Son_Father sf = son.new Son_Father();
        sf.drink();*/

        Son_Father sf = new Son_Father();
        sf.drink();

        Son son = new Son();
        //Son_Mother sm =son.new Son_Mother();
        //sm.cook();

    }

}

其他说明:
这里写图片描述
创建内部类对象的方法:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

举例: swing中的事件

1.4 ARRAYS: java.util.Arrays;

这里写图片描述
有一个字符串数组:
String [] array = {“2”,”13”,”12”,”4”};
我们要对这个数组的元素进行排序, “2” <“4”<”12”<”14” ,注意,这里是字符串了

这里写图片描述
这里写图片描述
按照自然顺序的结果,显然不是我们理想的结果,如果想按照自己的方式(数字)来排序;
这里写图片描述

我们要重写这个接口
这里写图片描述
中的:
这里写图片描述

package arrayspackage;

import java.util.Arrays;
import java.util.Comparator;

/**
 * 自定义类 实现了 Comparator 中的 compare方法
 * 
 * @author Administrator
 *
 */
class MyCompare implements Comparator<String> {
    public int compare(String o1, String o2) {
        return Integer.parseInt(o1) - Integer.parseInt(o2);
    };
}

public class TestSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String[] array = { "2", "13", "12", "4" };

        // 排序
        //Arrays.sort(array);

        // 排序实现2 两个参数

        Arrays.sort(array, new MyCompare());

        // 输出
        for (String string : array) {
            System.out.println(string);
        }

    }

}

第二种写法: 直接在参数位置创建接口的实现;

package arrayspackage;

import java.util.Arrays;
import java.util.Comparator;

/**
 * 简单一些
 * @author Administrator
 *
 */
public class TestSort2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String[] array = { "2", "13", "12", "4" };

        // 排序
        //Arrays.sort(array);

        // 排序实现2 两个参数

        Arrays.sort(array, new Comparator<String>() {
            public int compare(String o1, String o2) {
                return Integer.parseInt(o1) - Integer.parseInt(o2);
            };
        });

        // 输出
        for (String string : array) {
            System.out.println(string);
        }

    }

}

1.5 正则表达式:

1.6 参数传递值传递:

传递的是值(副本):
这里写图片描述

swap a:2,b :1
main中的 a:1,b :2

值传递(传递的是数组的地址):
这里写图片描述

swap中的输出~
3 4 5
main中的输出~
3 4 5

简单的面试题

package parameterpackage;

/**
 * 简单的面试题解析
 * 
 * @author Administrator
 *
 */
public class Test03 {

    /**
     * StringBuffer
     * @param sb1
     * @param sb2
     */
    public static void changeString(StringBuffer sb1, StringBuffer sb2) {
        //StringBuffer可变性
        sb1 = sb2; //指向发生了改变,sb1和sb2指向一致;  sb1->xyz  sb2->xyz
        sb2.append(sb1);// 在sb2指向的元素上增加了一个 sb1指向的元素;   他们(sb1 sb2)指向的那个元素变成了xyzxyz
        System.out.println("changeString  sb1 :" + sb1 + ", sb2:" + sb2);// xyzxyz  xyzxyz /
    }

    /**
     * 普通字符串的方法
     * @param a
     * @param b
     */
    public static void changeString(String a, String b) {
        a = b; //指向发生了改变 ,让a的指向和b的指向一致  ,让a也指向了xyz ,b指向的是xyz
        a = a + b; //  又有一个新的存储区域,存储的是a+b的结果(拼接)  a=>"xyzxyz" ,此时b指向的还是 xyz
        System.out.println("changeString a :" + a + ", b:" + b);//  xyzxyz xyz
    }

    /**
     * 程序入口
     * @param args
     */
    public static void main(String[] args) {

        //这里 看起来是一个String 引用类型,但是有一个什么问题,字符串特性"不变性"
        String a = "abc";
        String b = "xyz";

        changeString(a, b);
        System.out.println("main a :" + a + ", b:" + b);// 这里的指向还是原来的指向 abc  xyz



        StringBuffer sb1 = new StringBuffer("abc");
        StringBuffer sb2 = new StringBuffer("xyz");

        changeString(sb1, sb2);
        System.out.println("main : sb1 :" + sb1 + " , sb2: " + sb2);// abc xyzxyz 

    }

}

changeString a :xyzxyz, b:xyz
main a :abc, b:xyz
changeString sb1 :xyzxyz, sb2:xyzxyz
main : sb1 :abc , sb2: xyzxyz

package parameterpackage;

public class TestParameter {

    public void method01(int array[]) {

    }

    /**
     * 可变参数,捏可以传递数组或者数组元素,只能出现一次,最后一个参数
     * @param array
     */
    public void method02(int... array) {
        //array就是一个数组
        for (int i : array) {
            System.out.println(i);
        }

    }

    public static void main(String[] args) {
        TestParameter tp = new TestParameter();
        // 此时需要传递数组名
        int arr[] = { 1, 2 };
        // 能否直接传递数组元素? 数组都不用定义了?
        tp.method01(arr);

        //此时可以传递数组名或者数组的值
        tp.method02(arr);
        tp.method02(1,2,3);
        tp.method02(1,2,3,3,4,5,6);

    }

}

1.7 断言ASSERT:

了解:程序调试一种方式; 如果是生产环境,这个要去除;

package assertpackage;

public class Test01 {

    public static void main(String[] args) {

        // test03();
        // converString(null);
        converString("abc");
    }

    public static void converString(String str) {
        // 如果为str == null 中断
        assert str != null : "字符串不能为空";
        System.out.println("convertString");

    }

    /**
     * 
     */
    public static void test03() {
        for (int i = 0; i < 100; i++) {
            System.out.println(i);

            /*
             * if (i == 5) { break; }
             */

            // assert 条件结构;
            // assert 条件结构:"提示信息";
            // assert i==5:"断言的测试";
            // System.out.println("后续代码");
            // assert true : "提示信息"; //Dead code

            assert i != 5 : "提示信息";
            // -ea

        }
    }

}

1.8 总结:

1) Static关键字使用
2) 递归调用:
3) 内部类:
4) Arrays: sort的方法,记得明天要手写代码,记得提醒我!!!
5) 参数传递: 值传递(值 地址 (引用))
6) 断言:了解 assert -ea

1.9 作业布置:

预习 : 集合
编码实现对一个公司的员工进行简单的访问: 增加员工,删除员工,修改员工,查询员工(姓名 查询所有 根据员工编号等);

分析: 每个员工都应该是一个对象(Employee) ->一个公司有多个员工(数组或者集合来处理) ->针对数组的操作: ->增加员工,删除员工,修改员工,查询员工(姓名 查询所有 根据员工编号等

后续将上面的案例使用集合来处理 ->将数据和数据库-> Java+JDBC

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值