Day16知识总结

JVM内存分配:方法区、栈、堆、常量池

JVM内存分配:方法区、栈、堆、常量池

怎么得到一个对象

new 自己建的类 (自己创建的)

通过某个对象,调用其方法,得到其他对象(程序提供的)

通过类的静态方法,得到某个对象 (程序提供的)

得到对象的三种方法

拉姆达表达式(lambda)匿名函数

Lambda 表达式(lambda expression)是一个匿名函数,即没有函数名的函数
能够使用 Lambda 表达式的一个重要依据是必须有相应的函数接口
所谓函数接口,是指内部有且仅有一个抽象方法的接口

函数式接口 @FunctionalInterface

@FunctionalInterface , 函数式接口

接口内部,必须的只有一个抽象方法

只能修饰interface接口,不能修饰抽象类或者类

@FunctionalInterface
abstract class B{ public abstract void f();}
/B is not a functional interface 编译错误
@FunctionalInterface 只能修饰 interface接口

多个函数式接口的代码

@FunctionalInterface 
//函数式接口 注解 接口内部,有且仅有一个抽象方法
//@FunctionalInterface 只能修饰 interface接口
interface Demo1AInterface {
    //计算两个数之和
    int sum(int x,int y);
}

//B is not a functional interface 编译错误 
//@FunctionalInterface 只能修饰 interface接口

//@FunctionalInterface 
//abstract class B{
//    public abstract void f();
//}

interface BInterface{
    //判断是否大于18
    boolean isBigPeople(int age);
}
interface CInterface{
    //输出格式: name+","+word
    void sayHi(String name,String word);
}
interface DIterface{
    //产生一个随机整数
    int randomInt();
}

实现接口的三种方式

匿名内部类创建接口对象

匿名内部类,可用于一个接口有一个或一个以上抽象方法时,对接口创建对象

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

        Demo1AInterface a = new Demo1AInterface() {
            @Override
            public int sum(int x, int y) {
                return x + y;
            }
        };
        System.out.println("求和:" + a.sum(3, 9));

        BInterface b = new BInterface() {
            @Override
            public boolean isBigPeople(int age) {
                return age >= 18;
            }
        };
        System.out.println(b.isBigPeople(20));

        CInterface c = new CInterface() {
            @Override
            public void sayHi(String name, String word) {
                System.out.println(name + "," + word);
            }
        };
        c.sayHi("李华", "你好");

        DIterface d = new DIterface() {
            @Override
            public int randomInt() {
                return new Random().nextInt();
            }
        };
        System.out.println("随机生成的整数为:" + d.randomInt());
    }
}
lambda表达式的使用

必须满足接口中只有一个抽象方法,才能使用
若DIterface有两个抽象方法

interface DIterface{
    //产生一个随机整数
    int randomInt();
    //指定范围的随机生成
    int randomInt(int d);
}

此时DIterface接口不符合lambda语法规则[符合函数式表达式]
只能使用匿名内部类来重写

DIterface dIterface=new DIterface() {
           @Override
            public int randomInt() {
                return new Random().nextInt(10);
            }

            @Override
            public int randomInt(int bound) {
                return new Random().nextInt(bound);
            }
        };

lambda表达式必须满足接口中只有一个抽象方法,才能使用

函数参数格式(省略函数名字,省略参数类型 改变参数名字,确保参数个数)->{函数体}
lambda表达式 与引用类型绑定在一起的
参数名任意,但参数个数必须匹配的上
(a, b) -> {return a + b;}; 是个对象
Demo1AInterface aInterface = (a, b) -> { return a + b; }; 即将创建对象赋值给一个类型相同的引用变量

class TestLambda {
    public static void main(String[] args) {
//lambda表达式 对应的接口必须符合函数式接口特征[只有唯一一个抽象方法]
//函数参数格式(省略函数名字,省略参数类型 改变参数名字,确保参数个数)->{//函数体}
//若无参函数,直接写();若有参函数,写(参数名 参数个数必须相同)
//lambda表达式 与引用类型绑定在一起的
        Demo1AInterface aInterface = (a, b) -> {
         //参数名任意,但参数个数必须匹配的上
        //内部把a,b当接口中方法定义类型使用a、b(int类型)
            return a + b;
        };//(a, b) -> {return a + b;}; 是个对象
        System.out.println("求和:" + aInterface.sum(9, 3));

        BInterface bInterface=(h)->{
            return h>=18;
        };
         System.out.println(bInterface.isBigPeople(17));

        CInterface cInterface=(n,w)->{
            System.out.println(n+","+w);
        };
        cInterface.sayHi("ll","HI");

        //DIterface接口不符合lambda语法规则[符合函数式表达式]
        //只能使用匿名内部类来重写
//        DIterface dIterface=new DIterface() {
//            @Override
//            public int randomInt() {
//                return new Random().nextInt(10);
//            }
//
//            @Override
//            public int randomInt(int bound) {
//                return new Random().nextInt(bound);
//            }
//        };
        DIterface dIterface=()->{
            return new Random().nextInt(100);
            };

        System.out.println("随机生成的整数为:" + dIterface.randomInt());
    }
}
强制转,无需再赋值给引用类型的变量
       System.out.println("求和: "+((Demo1AInterface)(a,b)->{
        return a+b;
        }).sum(4,6));
例子二
class H{
    int k(Demo1AInterface a,int x,int y){
        return a.sum(x,y);
    };
    boolean b(BInterface b,int age){
        return b.isBigPeople(age);
    }
    void c(BInterface b,DIterface d){
        int r=d.randomInt();
        boolean b1=b.isBigPeople(r);
        if(b1)
            System.out.println("成年人");
        else
            System.out.println("未成年人");
    }
}

调用该类的方法

public class TestLambda2 {
    public static void main(String[] args) {
        H h = new H();
        int he = h.k((a1, b1) -> {
            return a1 + b1;
        }, 4, 6);
        System.out.println("he:" + he);
        boolean b2 = h.b((h2) -> {
            return h2 >= 18;
        }, 17);
        //调用c
        //方法调用: 参数类型,参数个数,参数返回值
        //方法定义: 方法签名(方法修饰符,返回值,方法名,参数) 方法体怎么写
        h.c((b3) -> {
            return b3 >= 18;
        }, () -> {
            return new Random().nextInt(20);
        });
    }
}

接口default 修饰方法,实现方法

jdk8之后,接口中可使用default修饰方法 写方法的实现 default修饰的方法 必须有方法体

若DIterface类加入default int randomInt(int d)已实现的方法

interface DIterface{
    //产生一个随机整数
    int randomInt();
    //指定范围的随机生成
    //default修饰的方法 必须有方法体
    default int randomInt(int d){
        return new Random().nextInt(d);
    }
}
public class TestLambda3 {
    public static void main(String[] args) {
        DIterface d=()->{
            return new Random().nextInt();
        };
        System.out.println("100以内的随机整数:"+d.randomInt(15));
        }

Object 是所有类的父类

定义class时 若未明确指明父类 则该类的父类就是Object
一般省略extends Object
Object 是所有类的父类,该类封装了类型中常用的属性和方法

继承hashCode方法

toString()

toString 显示成员变量的值[一般重写]
输出语句 输出某个引用的时候 本质调用了toString方法

//定义class时 若未明确指明父类 则该类的父类就是Object,一般省略extends Object
//Object 是所有类的父类,该类封装了类型中常用的属性和方法
public class Demo2Piont extends Object {
    int x;
    int y;
    public Demo2Piont(){
        super(); //省略
    }
    public void up(){
        y++;
    }

}
class TestPiont{
    public static void main(String[] args) {
        Class pointClass=Demo2Piont.class; //class是继承的
        Demo2Piont p=new Demo2Piont();
        Class pClass=p.getClass();//继承父类的getClass()方法
        //可继承;可重写
        //toString 显示成员变量的值[一般重写]
        String str=p.toString();//继承的toString;
        System.out.println(str);//day5.PointObject@43a25848
        System.out.println(p);//day5.PointObject@43a25848
        //输出语句 输出某个引用的时候 本质调用了toString方法
        int code=p.hashCode();//继承hashCode方法
        //一般重写equals方法
        //自定义比较规则[一般比较属性值是否相同]
        boolean b=p.equals(p);//继承父类的equals方法
        System.out.println(b);
    }
}

重写equals()方法

一般重写equals方法 自定义比较规则[一般比较属性值是否相同]

==

基本数据类型 判断数据值是否相同 ; 引用类型 判断引用类指向的地址是否相同[即是否为同一个对象]

equals()

父类Object中的一个方法 指定两个对象是否相等的比较规则[两个对象属性值]
默认比较两个对象地址是否相同 子类重写父类equals()方法
两个对象比较equals为true,只能说明属性值相等 但不能说明是同一个对象[String]

//== 基本数据类型 判断数据值是否相同 ; 引用类型 判断引用类指向的地址是否相同[即是否为同一个对象]
//equals 父类Object中的一个方法 指定两个对象是否相等的比较规则[两个对象属性值]
//默认比较两个对象地址是否相同 子类重写父类equals()方法
//两个对象比较equals为true,只能说明属性值相等 但不能说明是同一个对象[String]
public class Demo3Shape {
    int x;
    int y;
    public Demo3Shape(){

    }
    //重写toSting()
    public String toString(){
        return this.getClass()+"("+x+","+y+")";
    }
    //重写equals 比较两个点的值是否相等
    //自定义比赛规则
    public boolean equals(Object o){//重写
        //若null 则不等
        //若类型不同 则不等
        //若自己 说明相等
        //若类型相同 不是自己 则判断属性值是否相等
        if(o==null)
            return false;
        else {
            if(!(o.getClass()==this.getClass()))
                return false;
            else {
                if(o==this) //引用地址是否相等
                    return true;
                else {
                    //向下转换 强制数据类型转换
                    if(o instanceof Demo3Shape){
                        Demo3Shape s=(Demo3Shape)o;
                        if(s.x==this.x&&s.y==this.y)
                            return true;
                    }
                    return false; //不符合以上条件 说明不相等
                }
            }
        }
    }
}
class TestShape{
    public static void main(String[] args) {
        Demo3Shape s1=new Demo3Shape();
        s1.x=5;
        s1.y=10;
        Demo3Shape s2=new Demo3Shape();
        s2.x=5;
        s2.y=10;

        Demo2Piont p=new Demo2Piont();
        p.x=5;
        p.y=10;
        //输出语句 输出某个引用的时候 本质调用了toString方法
        System.out.println("========toString=======");
        System.out.println(s1);
        //class day5.Demo3Shape(5,10)
        System.out.println(s2.toString());
        //class day5.Demo3Shape(5,10)
        System.out.println(p.toString());
        //day5.Demo2Piont@60addb54
        
        System.out.println("==");
        System.out.println(s1==s1);//true
        System.out.println(s1==s2);//false
        
        System.out.println("=====equals=====");
        System.out.println(s1.equals(s1));//true
        System.out.println(s1.equals(s2));//true
        System.out.println(s1.equals(p));//false
        }
String类型中对父类equals()进行过重写
		String a1="a";
        String a2="abc";
        String a3=new String("a");
        String a4=new String("abc");
        String a5="abc";

        //String重写了equals()方法,用于比较值是否相等

        System.out.println("=====String====");
        System.out.println(a1==a2);//false
        System.out.println(a1==a3);//false
        System.out.println(a2==a3);//false
        System.out.println(a2==a4);//fasle
        System.out.println(a2==a5);
        //true 字符串常量池相同对象
        System.out.println(a2.equals(a3));//false
        System.out.println(a2.equals(a4));//true 对象不同 数据值相同
Objects.equals()工具方法

Objects.equals()工具方法 提供的方法函数 对两个对象进行判断等值判断
Objects.equals()提供的方法函数

        public static boolean equals(Object a, Object b) {
            return (a == b) || (a != null && a.equals(b));
        }

本质 还是会调用到定义的类的equals()方法
若重写过,以重写过的equals()方法为准
若未重写,则默认使用父类的equals()方法[比较两个对象的地址是否相等]

public class TestObjects {
    public static void main(String[] args) {
//在Demo2Piont类中未重写过equals()方法 
//则默认使用父类的方法[比较两个对象的地址是否相等]
        boolean b=Objects.equals(p1,p2);
        System.out.println("p1->p2: "+b);//p1->p2: false
    }
}

静态代码块

类中的代码块可以使用static修饰,则被称为静态代码块
若有代码,需在类加载前执行,则将代码块放入静态代码块中(静态代码块只执行一次)
非静态代码块[匿名代码块] 优先于构造器的调用[编译后 匿名代码块放置构造函数首位]
若代码块,需要在创建对象之前(构造器的首位)执行,则将代码块放入非静态代码块(非静态代码块[匿名代码块]执行n次)


public class StaticBlockDemo {
    public static void main(String[] args) {
        // ** 静态代码块,优先于静态方法的调用
        // *** 如果有什么代码,需要在类加载的时候,就执行,把这个代码放在静态代码块中(静态代码块只执行一次。)。
        Foo.show(); // -- 通过类名,直接调用静态方法。

        // ** 非静态代码,优先余构造函数内部的其他代码的执行。
        // ***  如果有代码,希望在调用构造函数的其他代码,都要先执行,可以使用非静态代码块(非静态代码块执行多次)。
        Foo f = new Foo();
        Foo f1 = new Foo();
    }
}
class  Faa{

}
class  Foo extends  Faa{
    public  Foo(){
        super();

        System.out.println("构造器函数");
    }
    { // 经过编译,这个内容,就放在了构造函数的内部代码之前了。
        System.out.println("非静态代码块");
    }
    static {
        System.out.println("这个是静态代码块");
    }

    public  void print(){
        System.out.println("这个是普通方法");
    }
    public static  void show(){
        System.out.println("这个是静态方法。");
    }
}

静态代码块

封装

//面向对象三大特性
//封装 通过private关键字对成员变量修饰 提供getter和setter方法对成员变量进行取值与赋值
//继承 A类通过extends关键字,继承B类;java单继承 一个子类只能有一个父类,一个父类有多个子类
//继承提供代码的重用性
//多态 对象具备多种状态 向上造型
public class Demo4FengStudent {
    private int age;
    private String hobby;
    private String name;
    private String sex;

    //自动生成get/set 鼠标右击[Alt+insert]、Generate..选项
    //set 给成员变量赋值 有参数,无返回值
    //get 获取成员变量的值 无参数,有返回值


    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}
class TestStudent{
    public static void main(String[] args) {
        Demo4FengStudent fS=new Demo4FengStudent();
        fS.setAge(12);
        fS.setName("LZH");
        fS.setHobby("追剧");
        fS.setSex("男");
        System.out.println("输出成员变量");
        System.out.println(fS.getAge()+","+fS.getName()+","+fS.getHobby()+","+fS.getSex());//12,LZH,追剧,男
    }
}

面向对象三大特性

封装,对象的成员变量尽量使用private私有进行修饰,将其属性和方法结合为一个独立的整体,并尽可能隐藏对象的内部实现细节
继承,多个子类中重复的代码抽取到父类中,子类通过extends关键字继承父类,可以直接使用,减少代码重复,提高代码的复用性
多态,对象具有多种状态,即向上造型,提高代码的可扩充性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值