知识点补充和扩展。
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