JavaSE_笔记03

一、内部内

  • 定义在 内部内部类外部类 有紧密的联系
    • 内部类 离开了外部类 将失去意义
  • 内部类 可以直接使用 外部类 的所有成员,【包括】私有成员

举个栗子

/** 内部内的基本语法
class Outer{ //外部类
	class Inner{ //内部类
	}
}
class Other{ //外部其他类
}

把【人*体】和【心脏】看作 类,【人*体】内有独特的  *NB*型血
【心脏】定义在了【人*体】,【人*体】与【心脏】有着紧密的联系
【人*体】离不开【心脏】,但【心脏】离开了【人*体】也将变得没有意义(不移植)
【心脏】可以使用【人*体】内独特的  *NB*型血
*/
class Test {
    public static void main(String[] args) {
        new 人体();
    }
}
class 人体 {
    //定义外部类成员变量
    String BloodType = "NB";
    public 人体() {
        new 心脏();
    }
    class 心脏 {//定义内部内
        //使用外部类成员变量BloodType
        public 心脏(){
            System.out.println("心脏正在使用 人体 的" + BloodType + "型血."); //输出: 心脏正在使用 人体 的NB型血.
        }
    }
}
  • 一般来说 内部内都会用 private 修饰,会导致无法在新类使用该类的内部类;对此,我们可以在外部内中提供一个方法来帮我们调用内部内的方法。
class Test {
    public static void main(String[] args) {
        new Outer().getIner;
    }
}
class Outer{
	private class Inner {
		public void showA(){System.out.println("Inner - showA");}
		public void showB(){System.out.println("Inner - showA");}
		public void showC(){System.out.println("Inner - showA");}
	}
	public void getIner(){
	Inner i = new Inner();
	i.showA();
	}
}

但是这样会造成一个问题,当我们需要访问内部内的其他方法时,需要创建新的getIner(),当内部内中方法有很多时,我们需要的getIner()会非常庞大
对此我们可以进行一点小小的优化,让getIner()方法返回一个Inner对象给我们使用,而不是通过它来调用内部内的成员


class Test {
    public static void main(String[] args) {
        //Inner inner = new Outer().getIner; 这样会报错,因为Inner对象是private修饰的
        Inter inner = new Outer().getIner();//接收到对象后就可以随意使用了
        inner.showA();
        inner.showB();
        inner.showC();
    }
}
interface Inter { //这时候我们可以创建一个接口让Inner实现,这样我们获取Inner对象的时候就可以用Inter接口来接收了
    public void showA();
    public void showB();
    public void showC();
}
class Outer{
    private class Inner implements Inter {
        public void showA(){System.out.println("Inner - showA");}
        public void showB(){System.out.println("Inner - showA");}
        public void showC(){System.out.println("Inner - showA");}
    }
    public Inner getIner(){
        return new Inner();
    }
}
  • 分类
    • 成员内部类
    • 静态内部类
    • 局部内部类
    • 匿名内部类

1. 成员内部类

  • 说明: 定义在外部类的成员位置(外部类的方法外),并且没有static修饰
    • 成员内部类的创建需要依赖于外部类对象
    • 成员内部类可以直接访问外部类的成员
    • 当内部类有与外部类重名的变量时,可使用 外部类.this.变量名
class Outer{
    //成员变量
    private String name = "张彪";
    int age = 666;

    //成员内部类
    class Inner{
        int age = 18;
        private String str = "是大衰哥!!!";
        public void showMsg(){
        	//可以看出,当内部类有与外部类重名的变量时,可使用 外部类.this.变量名
            System.out.println(age);            //输出: 18
            System.out.println(this.age);       //输出: 18
            System.out.println(Outer.this.age); //输出: 666
            //成员内部类可以直接访问外部类的私有成员
            System.out.println(age+ "岁的" + name + str); //输出: 18岁的张彪是大衰哥!!!
        }
    }
    public void Demo(){
        Inner inner = new Inner();
        inner.showMsg();
    }
}

2. 静态内部类

  • 说明: 定义在外部类的成员位置,并且有static修饰
  • 和静态方法相同,静态内部类只能访问静态成员,静态内部类不需要外部类创建对象就可以使用
  • 使用方法: 外部类名.内部类名.成员
class Outer{
	//静态成员变量
    static String name;
    int age;
    //静态内部类
    static class Inner{
        public void saySomething(){
            System.out.println(name);
            //System.out.println(age); 报错,静态只能访问静态
        }
    }
}

3. 局部内部类

  • 说明: 定义在外部类的局部位置(外部类的方法或作用域内),比如方法中,并且有类名
  • 不能被【static】修饰
  • 可以直接访问方法的成员
  • 可以直接访问局部内部类的成员
  • 可以直接访问外部类的成员
  • 创建对象要在方法内部或局部类的外部
//外部类
class Outer{
	//外部成员变量
    String name = "Outer";
    //外部类方法
    void Demo(){
    	//外部类成员变量
        String name = "Demo";
        //局部内部类
        class Inner{
        	//局部内部类成员变量
            String name = "Inner";
            public void saySomething(String name){
                System.out.println(name);            //输出: Demo; 可以直接访问方法的成员
                System.out.println(this.name);       //输出: Inner;可以直接访问局部内部类的成员
                System.out.println(Outer.this.name); //输出: Outer;可以直接访问外部类的成员
            }
        }
        //创建对象要在方法内部或局部类的外部
        new Inner().saySomething(name);
    }
}

4. 匿名内部类

  • 说明: 定义在外部类的局部位置,比如方法中,并且没有类名
    • 本质上是一个 【对象】,要注意匿名内部类是 没有类名
    • 是一个没有名字的局部内部类
    • 是一个一次性使用,用完就扔
  • 前提: 存在一个类或者接口,这里的类可以是具体类也可以是抽象类
  • 编译之后,会产生一个单独的.class字节码文件
//格式:
new 类名或者接口名{
	//重写方法
}
interface Inter{
	void show();
}
class Outer{

	new Inter(){
		@Override
		public void show(){
			System.out.println(""匿名内部类);
		}
	}.show(); //因为匿名内部类本质上是 对象,所以可以直接调用方法

	//因为匿名内部类本质上是 对象,所以可以被其实现的接口接收
	Inter i = new Inter(){
		@Override
		public void show(){
			System.out.println(""匿名内部类);
		}
	};
	i.show();
}

二、lambda表达式

  • 说明: 是匿名内部类的简化版,但不是所有匿名内部类都可以用lambda表达式简化,只有 函数式接口  的匿名内部类才可以使用Lambda表达式来进行简化
    • 函数式接口: 只有一个抽象方法的接口称为函数式接口
  • 格式: (形参列表) -> {方法体}
    *
  • 编译之后,不会生成一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

举个栗子

  1. 面向对象思想:匿名内部类实现
//面向对象思想
interface inter {
    void show(String name);
}
class Outer {
    public static void main(String[] args) {
    	//匿名内部类实现
        showMsg("张彪", new inter() {
            @Override
            public void show(String name) {
                System.out.println(name + "是我的好大儿!!!");//输出: 张彪是我的好大儿!!!
            }
        });
    }
    public static void showMsg(String name, inter i){
        i.show(name);
    }
}
    • 函数式思想:Lambda表达式实现
//函数式思想
interface inter {
    void show(String name);
}
class Outer {
    public static void main(String[] args) {
    	//Lambda表达式实现
        showMsg("张彪", name -> System.out.println(name + "是我的好大儿啊!!!") );//输出: 张彪是我的好大儿啊!!!
    }
    public static void showMsg(String name, inter i){
        i.show(name);
    }
}

Lambda表达式还可以更简洁

  • 1. 当方法体只有一句时,可以一起省略 【大括号 {}】 和 语句后面的【分号 ;】
    2.当方法体只return一个结果,可以一起省略 【return】、【大括号 {}】和【分号 ;】
    3. 当参数只有一个,可以省略【小括号 ()】和【参数类型】
interface inter1 {void show();}				//无参、无返回值
interface inter2 {String show();}			//无参、有返回值
interface inter3 {void show(String name);}	//有参、无返回值
interface inter4 {String show(String name);}//有参、有返回值

class Outer {
    public static void main(String[] args) {

        String str = "有参";
        showMsg1(() -> {
            System.out.println("无参、无返回值的Lambda表达式");
        });
        //当方法体只有一句时,可以一起省略 【大括号 {}】 和 语句后面的【分号 ;】
        showMsg1(() -> System.out.println("一起省略 【大括号 {}】 和 语句后面的【分号 ;】的 无参、无返回值的Lambda表达式"));
        System.out.println("\n==============================我是分割线==============================\n");

        showMsg2(() -> {
            return "无参、有返回值的Lambda表达式";
        });
        //当方法体只return一个结果,可以一起省略 【return】、【大括号 {}】和【分号 ;】
        showMsg2(() -> "一起省略 【return】、【大括号 {}】和【分号 ;】的 无参、有返回值的Lambda表达式");
        System.out.println("\n==============================我是分割线==============================\n");

        showMsg3(str, (String name) -> {
            System.out.println(str + "、无返回值的Lambda表达式");
        });
        //当参数只有一个,可以省略【小括号 ()】和【参数类型】
        showMsg3(str, name -> System.out.println("省略【小括号 ()】、【大括号 {}】 和 语句后面的【分号 ;】的 " + str + "、无返回值的Lambda表达式"));
        System.out.println("\n==============================我是分割线==============================\n");

        //省略 【小括号 ()】、【大括号 {}】 、 语句后面的【分号 ;】、【return】
        showMsg4(str, (String name) -> {
            return str + "、有返回值的Lambda表达式";
        });
        showMsg4(str, name -> "省略【小括号 ()】、【大括号 {}】 、 语句后面的【分号 ;】、【return】的" + str + "、有返回值的Lambda表达式");
    }

    public static void showMsg1(inter1 i) {
        i.show();
    }

    public static void showMsg2(inter2 i) {
        String result = i.show();
        System.out.println("inter2 返回值:" + result);
    }

    public static void showMsg3(String name, inter3 i) {
        i.show(name);
    }

    public static void showMsg4(String name, inter4 i) {
        String result = i.show(name);
        System.out.println("inter4 返回值:" + result);
    }
}

方法引用
说明: 特定情况下简化Lambda表达式,使语言的构造更紧凑简洁,减少冗余代码。( 将 Lambda表达式再简写一点)
格式: 类 :: 方法

  • 当所有参数都交由函数式接口使用时,可使用方法引用

举个栗子

class Demo {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>();
		list.add("666");
		list.add("777");
		list.add("888");
		//list集合的所有元素交由【System.out 下的 print() 方法】使用
		list.forEach(System.out::print);//输出: 666777888
	}
}

三、Math 数学工具类

  • 该类的所有方法都是静态的

  • 该类被【final】修饰,没有子类

  • 该类构造方法被【private】修饰,无法创建对象

  • 常用方法:

    • double sqrt​(double a); 返回 double值的正确舍入的正平方根。
    • double abs(double d); 获取传入参数的绝对值
    • double ceil(double a) 向上取整
    • double floor(double a); 向下取整
    • int round(double d) 四舍五入
    • int max(int a,int b); 获取最大值
    • double pow(double a,double b); 获取第一个参数的第二个参数次幂 2^3
    • double random(); 获取一个[0.0,1.0)

举个栗子

class MathTest {
    public static void main(String[] args) {
        System.out.println("Math.sqrt(num):\t" + Math.sqrt(4));        //计算【4】开平方根;  输出: Math.sqrt(num):	2.0
        System.out.println("Math.abs(-4):\t\t" + Math.abs(-4));        //计算【-4】的绝对值; 输出: Math.abs(-4):		4
        System.out.println("Math.ceil(4.4):\t" + Math.ceil(4.4));      //【4.4】向上取整;   输出: Math.ceil(4.4):	5.0
        System.out.println("Math.floor(4):\t\t" + Math.floor(4));      //【4.4】向下取整;   输出: Math.floor(4):	4.0
        System.out.println("Math.round(4.4):\t" + Math.round(4.4));    //【4.4】四舍五入;   输出: Math.round(4.4):	4
        System.out.println("Math.pow(4, 4):\t" + Math.pow(4, 4));      //计算【4 的 4 次方】 输出: Math.pow(4, 4):	256.0
        System.out.println("Math.random():\t\t" + Math.random());      //获取一个[0.0,1.0)  输出: Math.random():	0.9625000419745177 【随机数,不是固定的】
        System.out.println("Math.max(4, 44):\t" + Math.max(4, 44));    //【4, 44】的最大值   输出:Math.max(4, 44):	44
    }
}

四、System 系统工具类

方法:

    Properties getProperties():  获取系统信息
    void exit(int a);   退出JVM   Bowser/Server   【别用】
    long currentTimeMillis();  获取当前系统时间的毫秒值    主要用来计算某段程序执行时间。
    arrayCopy(Object src,int srcOff,Object dest,int destOff,int len);  数组拷贝
        Object src: 原数组
        int srcOff: 原数组拷贝的起始索引
        Object dest:目标数组
        int destOff:目标数组拷贝的起始索引
        int len:    拷贝的数组元素个数

举个栗子

//举不动了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值