Java面向对象

面向对象

1.世界是由什么构成的?

  • 物理:分子和原子
  • 化学:不同的元素构成

作为Java开发:应该站在分类学家的角度看问题

  • 植物类
  • 动物类
    • 哺乳类
      • 爬行类
        • 有足类(蜥蜴)
        • 无足类(蛇)
    • 非哺乳类

2.类和的对象的关系—面试题

类:具有相同特征的事物,抽象出来的概念(直观点说就是想出来的)

对象:现实世界中客观存在的事物(比如:张三,李四 都是现实存在的人)

面试题:类和对象是什么关系?

答案:类是对象的模板,因为只有创建好类,才可以通过类创建不同的实例(对象)

对象是类的实例,可以通过一个类创建无数个实例

3.如何编写一个类

类:具有相同特征的事物抽象出来的

  • 静态特征(属性):性别 身份证号…

  • 动态特征(方法):学习 吃饭 打游戏…

    public class 类名{
    	属性:性别 身份证号
    	方法:学习 吃饭 打游戏
    }
    

4.如何定义属性和方法

  • 属性语法:

    //访问修饰符 数据类型 属性名:
    public String name;
    
  • 方法语法:

    //访问修饰符 返回值类型 方法名称(参数){
    	//方法实现内容
    //}
    
    比如:
    public static void main(String[] args){
        
    }
    
    • 访问修饰符:是Java为了控制属性和方法的访问权限

      面试题:四种访问修饰符的使用区别

      访问修饰符 public(公开的) protected(受保护的) 默认(省略) private(私有的)
      本类
      同包
      子类
      其他
    • 返回值类型:表示方法在运行后需要的结果

      通常:必须添加return表示对应的返回结果

      特殊:void表示不需要返回,可以不写return结果的

      public String test(){
          String name="100";
          return name;
      }
      
      //特殊情况
      //因为A是B的父类 B的类型也属于A的类型
      public A test2(){
      	A a=new A();
      	B b=new B();
      	return b
      }
      class A{
      }
      //B继承了A类
      class B extends A{
          
      }
      
    • 参数:

      • 形式参数(形参):在方法定义的时候写入的参数

        //abc就是形参,一般形参需要写数据类型和形参名
        public void test(String abc)
        
      • 实际参数(实参):在方法调用的时候传入实际的值

        //name就是实参  实参名称和形参名称不需要一样,但是类型必须一样
        String name="张三";
        test(name);
        
  • 如何使用类中的属性和方法?

    //数组使用
    int[] nums=new int[5];
    nums.length
        
    //1.创建对象(需要先有类)
    类名 对象名=new 类名();
    Scanner sc = new scanner(System.in);
    Dog d = new Dog();
    
    //2.通过对象名.属性 调用属性 或者给属性赋值
    String s=d.name
    d.name="大黄";
    
    //3.通过对象名.方法(实参)
    d.eat("骨头");
    

    面试题:成员变量和局部变量的区别是什么?

    • 作用范围不同:成员变量可以在全类中使用,局部变量在哪里声明的在哪里使用
    • 优先级不同:如果局部变量和成员变量同时存在,局部变量优先于成员变量(就近原则)但是可以通过this关键字直接调用成员变量
    • 默认值不同:成员变量会有默认值,所以不需要赋值也可以使用,局部变量必须先赋值才可以使用因为它没有默认值

    面试题:char类型有几种赋值方式?

    答案:1.可以通过单引号赋值单个字符

    ​ 2.可以赋值ASCII码,ASCII只是表示计算机键盘中的按键 65-90是A-Z 97-122是a-z

    ​ 3.可以赋值Unicode编码,可以涵盖计算机所出现的所有字符,一共65535个,语法:\u4567,这里包 含中文,所以char类型也可以存储中文

5.constructor构造方法

构造方法:也叫构造器,也叫构造函数,是Java中一种特殊的方法,因为构造方法没有返回值这个概念,正常创建对象时,都需要依赖这个方法,如果类中没有定义构造方法,也会存在一个默认的无参构造方法

5.1构造方法的语法规则
  • 不能定义返回值(void都不能写)

  • 构造方法名称必须和类名一样

  • 构造方法可以提供多个,而且存在默认的无参构造

    public class People{
        //无参构造方法
    	public People(){
    		name="未知";
            age=0;
    	}
        
        //带参数的构造方法
        public People(String name,int age){
            this.name=name;
            this.age=age;
        }
      //构造方法可以提供多个,前提是参数列表一定要不同
        //参数类型  参数个数  参数顺序
        public People(int a){
            
        }
    }
    
    //构造方法:
    //1.用于创建对象  new 对象() 就是调用构造方法的过程
    //2.一般用于给属性做初始化
    public class Student {
        String name;
        String sex;
        int age;
        public void print(){
            System.out.println("我是: " + name+",我今年"+age+"岁"+",性别:"+sex);
        }
        //默认会存在一个无参构造,但是如果手动编写,默认的就会失效
        public Student(){
            System.out.println("执行了无参构造方法");
        }
        //构造方法可以提供多个(前提是参数列表不同,类型,个数,顺序)
        public Student(String name){
            System.out.println("执行了有参构造方法");
        }
        public Student(String a,int b){
    
        }
        public Student(int a,String b){
    
        }
        public Student(int a,int b){
    
        }
        public Student(String name,String sex,int age){
            this.name = name;
            this.age = age;
            this.sex=sex;
        }
        //构造方法为什么可以提供多个,因为Java支持方法重载
        //方法重载:
    }
    class TestStudent{
        public static void main(String[] args) {
            Student stu = new Student("张三");
            Student stu2 = new Student(10,"bb");
            Student stu3 = new Student(10,20);
            Student stu4 = new Student("10",20);
            
            System.out.println(stu);
            //Student s=new Student();
            //s.name="张三";
            //s.sex="男";
            //s.age=10;
            //s.print();
            Student s=new Student("张三","男",18);
            s.print();
        }
    
    }
    
    
5.2方法重载overload—面试题

一般情况下发生在同一个类中,要求方法名一样,参数列表不同(个数,顺序,类型),跟返回值无关

public class Dog {
    //重载:一个类中方法名相同,参数不同,返回值无关
    public void play(){

    }
    public int play(String msg){
        return 0;
    }
    //还可以传递可变长的参数 语法:类型 ...  参数名
    //以后 传递0-多个参数 都可以通过可变长参数来处理
    //形成一个数组参数
    public void play(String ... s){
        for(String args:s){
            System.out.println(args);
        }
    }
    public static void main(String[] args) {
        Dog d = new Dog();
        d.play("aaa");
        d.play();
        d.play("a","b","c","d");
        //jdbc 肯定要关闭资源 但是资源如果不确定 就可以通过可变长参数处理
        //close(ResultSet,PreparedStatement, Connection)
        //close(PreparedStatement, Connection)

    }
}

6.this关键字用法—面试题

this表示当前类的对象

  • 用法1:this.属性名,调用类中的成员变量 —常用

  • 用法2:this.方法(),调用类中的普通方法(静态方法不可以)

  • 用法3:this() 和 this(参数) 调用本类无参和有参构造方法

    • 特殊:this()和this(参数)必须写在第一行代码,并且只能用在构造方法中

      //this关键字
      public class User {
          int id;//用户编号
          String username;//账号
          String password;//密码
          double money;//存款
          public User() {
              //必须写在构造方法第一行代码,否则报错
              //不要循环调用
              this(15.5);
              System.out.println("调用无参构造");
              //this(15.5) 错误的
          }
          public User(double money){
              //给属性赋初值
              this.money = money;
              //用法偏少
              this.setMoney(100);
              //用法偏多
              setMoney(200);
              System.out.println("调用一个参数构造");
          }
          public User(String username, String password) {
              System.out.println("调用两个参数构造");
              this.username = username;
              this.password = password;
          }
          public User(String username, String password, double money) {
              this(username, password);
              this.money = money;
              System.out.println("调用三个参数构造");
              //this.username = username;
              //this.password = password;
              //this.money = money;
          }
          //存款的方法
          public void setMoney(double money) {
              this.money+=money;
          }
      
          //静态方法
          public static void main(String[] args) {
              //this.money  this不能使用在静态的方法中
              new User("admin", "123456", 100.0);
          }
      }
      

面试题1:为什么普通方法不能使用this()?

答案:this() 调用无参构造方法,目的是为了创建对象,普通方法必须通过对象才可以调用,两者的目的相互冲突

面试题2:为什么(static)静态方法不能使用this?

答案:this表示当前对象,static属于类本身,随着类加载才会执行,因为先有类才有对象,等执行静态方法的时候,对象可能还没来得及创建,所以使用时机不对

7.static修饰符用法 — 经典面试题

static表示一个修饰符,可以修饰属性,修饰方法,修饰代码块,表示静态的意思

  • 修饰属性:静态属性或者类属性,是属于类的不是属于对象的,无论创建多少个对象都会共享同一个静态变量,通常推荐通过类名.静态属性调用

    对象名.静态属性 ---不推荐,因为它属于类
    类名.静态属性 ---推荐方式,省略创建对象步骤
    比如:System.in;
    
  • 修饰方法:静态方法,也叫类方法,也推荐通过类名调用

    注:静态方法只能使用静态变量和静态方法;普通方法:可以调用普通属性和方法 ,也可以调用静态属性和方法

  • 修饰代码块:静态代码块,会随着类加载最先执行,而且只会执行一次,而且只能调用静态属性和静态方法

    • 静态代码块应用场景:适合给程序属性做初始化,加载配置文件(jdbc 数据库连接文件)

    • 代码块分类:

      • 构造代码块
      • 普通代码块
      • 静态代码块:在类加载的时候,做一些数据初始化的时候使用
      public class Demo3 {
          {
              System.out.println("构造代码块,new对象的时候执行");
          }
          public Demo3() {
              System.out.println("构造方法");
          }
          public void test(){
              {
                  System.out.println("普通代码块,方法调用的时候执行");
              }
          }
          static {
              System.out.println("静态代码块,类加载才执行,而且执行一次");
          }
      
          public static void main(String[] args) {
              Demo3 d1=new Demo3();
              Demo3 d2=new Demo3();
              d1.test();
              d1.test();
              d2.test();
          }
      }
      

    面试题:为什么要使用static?或者static有什么优势?

    1.可以不通过对象来调用属性和方法,推荐使用类名调用

    2.静态变量是属于类的,不同的对象共享同一个静态变量,有一个对象修改了,其他对象使用也会修改

    3.静态变量,存储在内存中方法区(静态区),无论创建多少个对象,不用花费额外的空间再来保存,比较节省内存

8.面向对象基本特征 — 经典面试题

  • 封装:将类中的属性私有化(private),为了让其他类不能随便使用我的属性,还要对外提供两个公开的方法(set XX和get XX)用于设置和获取对应的属性,这样就可以根据我的业务需要设置我的属性规则,就可以防止数据非法,提高了安全性

    原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为

    //手机类:进行封装
    //手机型号(IOS,安卓,鸿蒙) 颜色 价格(0-5000)
    //1.属性私有化(不让其他类随便使用我的属性)
    //2.对外提供 get 和 set 获取和设置属性(用户可以在 set 和 get 设置自己的属性规则)
    public class Phone {
        private String type;
        private String color;
        private double money;
        //设置手机型号的方法 setType 一般是需要带参数的
        public void setType(String type){
            if("IOS".equals(type) || "安卓".equals(type) || "鸿蒙".equals(type)){
                this.type = type;
            }else{
                System.out.println("输入的手机型号不合法,默认:安卓");
                this.type="安卓";
            }
        }
        //获取手机型号的方法 getType 一般是需要带返回值的
        public String getType(){
            return type;
        }
        //设置获取颜色(银色,黑色)
        //alt+insert(ins) 快捷生成 构造 get set ....
        public void setColor(String color){
            if("银色".equals(color) || "黑色".equals(color)){
                this.color = color;
            }else {
                System.out.println("输入的手机颜色不合法,默认:黑色");
                this.color="黑色";
            }
        }
        public String getColor(){
            return color;
        }
        //设置获取价格(0-5000)
        public void setMoney(double money){
            if (0<=money && money<=5000){
                this.money = money;
            }else {
                System.out.println("输入的手机价格不合法,默认:5000");
                this.money=5000;
            }
        }
        public double getMoney(){
            return money;
        }
    }
    class TestPhone{
        public static void main(String[] args) {
            Phone p=new Phone();
            p.setType("IOS");
            p.setColor("银色");
            p.setMoney(4000);
            System.out.println(p.getType());
            System.out.println(p.getColor());
            System.out.println(p.getMoney());
            System.out.println("----------------------");
            Phone p1=new Phone();
            p1.setColor("绿色");
            p1.setMoney(5000);
            p1.setType(null);
            System.out.println(p1.getType());
            System.out.println(p1.getColor());
            System.out.println(p1.getMoney());
        }
    }
    
  • 继承:将很多类共同的特征(属性和方法),提取出通过一个类完成,这样其他类就可以继承这个类,那么也会具有这些共同特征,可以防止代码冗余,使用extends关键字来继承指定的类,这个类一般称之为父类(基类),子类可以继承父类的非私有资源

    注意:Java只支持单继承,一个类只能有一个直接父类,但是可以多重继承,因为父类还可以继承其他类

    //继承        子类        父类
    public class Cat extends Pet{
        String color;
        @Override
        public void print(){
            System.out.println("猫的基本信息:");
            //子类可以使用父类的非私有资源
            System.out.println(name);
            System.out.println(color);
            System.out.println(health);
            System.out.println(love);
    
        }//颜色
    }
    class Tiger extends Pet{
        String type;//品种
        //方法的重写:为了更好的体现出子类自己的特性
        @Override//用于标注是否是重写,可以省略
        public void print(){
            System.out.println("老虎的基本信息:");
            //子类可以使用父类的非私有资源
            System.out.println(name);
            System.out.println(type);
            System.out.println(health);
            System.out.println(love);
    
        }
    }
    //宠物类:老虎类和猫类都属于宠物类的子类
    class Pet{
        //猫类和老虎类共同的特征(属性和方法)
        String name;
        int health;
        int love;
        public void print(){
            System.out.println("宠物的基本信息:");
            System.out.println(name);
            System.out.println(health);
            System.out.println(love);
            //父类不能使用子类的资源
            //System.out.println(type);
        }
    }
    class Test{
        public static void main(String[] args) {
            Cat c = new Cat();
            c.name="花花";
            c.health=100;
            c.love=50;
            c.color="橘猫";
            c.print();
            Tiger t = new Tiger();
            t.name="小王";
            t.health=100;
            t.love=20;
            t.type="东北虎";
            //调用哪个方法 需要t对象指向的是谁,这里指向的是老虎类
            t.print();
        }
    }
    
    • 方法重写Override—面试题:

      1.访问修饰符:可以相同或者不能严于父类

      2.返回值:可以相同或者是其子类

      3.方法名:必须相同

      4.参数列表:必须相同

      5.不能抛出比父类更多的异常

    • super关键字使用方式和this关键字一样,super泛指当前父类对象

      1.this.属性   this.方法
      2.this()     this(参数)
      
      3.super.属性   super.方法
      4.super()     super(参数)  调用父类有参无参构造
      

      注:Java类构造方法中,默认第一行会添加super()

      面试题:父类静态代码块 父类构造方法 父类构造代码块 子类静态代码块 子类构造方法 子类构造代码块 他们的执行顺序是什么?

      答案:父类静态代码块 --> 子类静态代码块 --> 父类构造代码块 --> 父类构造方法 -->子类构造代码块 -->子类构造方法

  • 多态—难点:

    同一个类的对象调用相同的方法时,可以有不同的表现形式,或者同一个类型,使用不同的实例(new 对象)会执行不同的操作

    比如:打印机 – 黑白打印机 —>打印黑白信息

    ​ --彩色打印机 —>打印彩色信息

    • 实现多态前提:

      • 满足类的继承

      • 方法的重写

      • 父类引用指向子类对象

        父类 对象1 = new 子类1();
        父类 对象2 = new 子类2();
        //结果:对象.方法() 就会运行子类重写后的方法
        
    • 多态调用成员的特点

      • 变量调用:编译看左边,运行也看左边
      • 方法调用:编译看左边,运行看右边
      public class Test {
          public static void main(String[] args) {
              Animal a = new Dog();
              //调用成员变量:编译看左边,运行也看左边
              //编译看左边:Java在编译代码的时候,会看左边的父类中有没有这个变量,
              //如果有,编译成功,如果没有,编译失败
              //运行也看左边:Java运行代码的时候,实际获取的就是左边父类中成员变量的值
              System.out.println(a.name); //动物
      
              //调用成员方法:编译看左边,运行看右边
              //编译看左边:Java在编译代码的时候,会看左边的父类中有没有这个方法,
              //如果有,编译成功,如果没有,编译失败
              //运行看右边:Java运行代码的时候,实际上运行的是子类中的方法
              a.show(); //Dog-----show方法
          }
      }
      class Animal{
          String name = "动物";
          public void show(){
              System.out.println("Animal-----show方法");
          }
      }
      class Dog extends Animal{
          String name = "狗";
          @Override
          public void show(){
              System.out.println("Dog-----show方法");
          }
      }
      class Cat extends Animal{
          String name = "猫";
          @Override
          public void show(){
              System.out.println("Cat-----show方法");
          }
      }
      
    • 多态的优势

      • 在多态形式下,右边对象可以实现解耦合,便于扩展和维护
      • 在定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
    • 多态的弊端

      • 不能调用子类的特有功能,解决方案:变回对应子类类型

9.抽象类

9.1抽象方法

方法定义和原来一样,区别在于,抽象方法只有方法的声明部分,没有方法的实现部分

//方法的声明部分
public void test(){
	//方法实现部分
}

//抽象方法需要通过关键字abstract
public abstract void test();
9.2抽象类特点—面试题
  • 抽象类不能被实例化(不能被new)
  • 抽象类里面可以没有抽象方法,但是有抽象方法的类一定是抽象类
  • 抽象类可以有普通属性和构造方法
  • 如果子类继承父类是抽象类,子类必须实现里面所有的抽象方法,否则子类也是抽象类
9.3final关键字的用法—面试题
  • final可以修饰类:表示这个类是最终类,表示这个类不能被继承

  • final可以修饰属性:表示这个属性是最终属性,说明这个属性一旦赋值不能修改,一般我们称之为常量(命名规则都要大写)

  • final可以修饰方法:表示这个方法是最终方法,这个方法不能被重写

    //测试final修饰符
    public final class TestFinal {
        //方法不能被重写
        public final void testMethod() {
    
        }
        //final修饰属性是常量 必须先赋值,一旦赋值不能修改
        final String sex="男";
        //final修饰属性 如果我不想直接赋值 怎么解决
        final static double pai;
        static {
            pai=3.1415926;
        }
    //    public TestFinal() {
    //        this.pai=3.14;
    //    }
    }
    //final修饰的类不能继承
    //class Child extends TestFinal{
    //
    //}
    class MyError extends Error{
    
    }
    

面试题1:Java是否可以写一个类去继承String或者Error类

答案:因为String是final修饰的类,不能被继承,Error不是final修饰的类,可以自定义类去继承Error

面试题2:abstract和final修饰符是否可以同时使用,为什么?

答案:abstract修饰的类属于抽象类,目的就是让子类实现(重写)我的方法;final修饰的类不能被继承,方法也不能被重写,两者有冲突,所以不能一起使用

10.特殊的抽象类(接口)

接口:相当于一个特殊的抽象类,本身就是一种规范和约定,如果想使用接口,就必须符合它的规范和约定,它里面的约定和规范就是里面的抽象方法,相比抽象类,里面的方法一般都是抽象方法

//测试接口:关键字interface
public interface MyInterface {
    //特点1:接口的所有属性都是常量(默认修饰符 public static final)
    public static final String name="a";
    String sex="male";
    //特点2:接口没有构造方法
//    public MyInterface(){
//
//    }
    //特点3:接口的方法都是抽象方法 不能有普通方法
    //默认修饰符都是 public abstract
    public abstract void test();
    void test2();
    //public void test3(){}
    //特点4:接口和接口 支持多继承 ; 类和类 单继承
    //      类和接口  表示实现  支持多实现
    //特点5:不能实例化
    //特点6:jdk1.8 接口支持静态方法和默认方法
    public static void method(){

    }
    //接口表示这个方法不强制要求你需要重写
    public default void method2(){}
}
interface MyInterface1 extends MyInterface2,MyInterface3 {
    void test1();
}
interface MyInterface2 {
    void test2();
}
interface MyInterface3 {
    void test3();
}
class My implements MyInterface3,MyInterface2 {
    @Override
    public void test3() {

    }

    @Override
    public void test2() {

    }
}
class My2 implements MyInterface1 {
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }

    @Override
    public void test3() {

    }
}
10.1 接口的特点
  • 接口的所有属性都是常量(默认修饰符 public static final)

  • 接口没有构造方法

  • 接口的方法都是抽象方法,不能有普通方法,默认修饰符都是 public abstract

  • jdk1.8后,接口支持静态方法和默认方法

    • 默认方法注意事项
      • 默认方法不是抽象方法,所以不强制被重写,但是如果被重写,重写的时候去掉default关键字
      • public可以被省略,default不能省略
      • 如果实现了多个接口,多个接口中存在名字相同的默认方法,子类就必须对该方法进行重写
    • 静态方法注意事项
      • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
      • public可以被省略,static不能省略
      • 静态方法不能被重写
  • 接口不能被实例化

  • 接口和类之间是实现关系,通过implements关键字表示

  • 接口的子类(实现类)要么重写接口中的所有抽象方法,要么是抽象类

接口和类之间的实现关系,可以单实现,也可以多实现,实现类还可以在继承一个类的同时实现多个接口

public calss 类名 implements 接口名1,接口名2{}
public class 类名 extends 父类 implements 接口名1,接口名2{}
10.2 适配器设计模式

解决接口与接口实现类之间的矛盾问题,当一个接口中抽象方法比较多,但是我只要使用其中一部分的时候,就可以使用适配器设计模式

  • 实现步骤:
    • 编写中间类XXXAdapter,实现对应的接口
    • 对接口中的抽象方法进行空实现(重写)
    • 让真正的实现类继承中间类,并重写需要用的方法
    • 为了避免其他类创建适配器类的对象,中间的适配器类可以用abstract进行修饰

11.特殊的接口(函数式接口)—了解

函数式接口:表示只有一个抽象方法,其他的常量默认方法除外,一般可以使用@FunctionalInterface来声明,也是jdk1.8特性

//函数式接口
@FunctionalInterface
public interface MyFunction {
    public void test();
}
@FunctionalInterface
interface MyFunction2 {
    public int getNum(int a, int b);
    String name="java";
    public default void test(){
        //Consumer
        //Predicate
        //Comparator
    }
}
//函数式接口的应用场景:适用于给lambda表达式使用
11.1Lambda表达式

lambda表达式就是用于描述函数式接口,因为函数式接口里面有且只有一个抽象方法,而lambda也只能描述一个方法

  • 语法规则1:

    () -> {}
    ():就表示方法的参数列表
    ->:就是间隔符
    {}:就表示方法的实现部分
    
  • 语法规则2:(数据类型 形参名) -> {} 数据类型是可以省略的

    MyFunction2 my3 = (a,b)->{...}
    
  • 语法规则3:当接口的抽象方法只有一个参数的时候,数据类型和()都可以省略

    //函数式接口
    @FunctionalInterface
    public interface MyFunction {
        public void test();
    }
    @FunctionalInterface
    interface MyFunction2 {
        public int getNum(int a, int b);
        String name="java";
        public default void test(){
            //Consumer
            //Predicate
            //Comparator
        }
    }
    @FunctionalInterface
    interface MyFunction3 {
        public void test(int a);
    }
    //函数式接口的应用场景:适用于给lambda表达式使用
    class TestLambda{
        public static void main(String[] args) {
            MyFunction my = new MyFunction(){
                @Override
                public void test() {
                    System.out.println("测试1代码");
                }
            };
            //利用Lambda表达式 也可以实现上面的过程
            MyFunction my2=() -> {
                System.out.println("测试2代码");
            };
            my.test();
            my2.test();
            MyFunction2 my3 = (int a,int b) ->{
                System.out.println(a+" "+b);
                return a+b;
            };
            //可以省略形参类型
            MyFunction2 my4=(a,b)->{
                return 10;
            };
            //一个参数 还可以继续省略()
            MyFunction3 my5= a ->{
            };
            //如果方法实现部分只有一句话 也可以省略{}
            MyFunction3 my6=a-> System.out.println(a);
            //如果方法实现部分有返回值,并且只有一句话,{}和return都可以省略
            MyFunction2 my7 = (a,b) ->a+b;
            int result = my3.getNum(2,3);
            System.out.println(result);
        }
    }
    
  • 语法规则4:不是Lambda语法,可以借助于其他类写好的静态方法来实现我自己的函数式接口方法

    要求:静态方法 参数和返回值必须一样

    语法:函数式接口  名称=类名::方法名;
    
    import java.util.Arrays;
    public class TestSortLambda {
        public static void main(String[] args) {
            //借助于Arrays.sort() 来实现我的函数式接口
            //要求:参数和返回值一致
            MySort my= Arrays::sort;
            int[] nums={3,1,5,4,2};
            my.mySort(nums);
            System.out.println(Arrays.toString(nums));
        }
    }
    interface MySort{
        public void mySort(int[] a);
    }
    class MyTest{
        public static String concat(String a, String b){
            return a+b;
        }
    
        public static void main(String[] args) {
            MyString my=MyTest::concat;
            String result=my.XXX("java","script");
            System.out.println(result);
        }
    }
    interface MyString{
        String XXX(String a, String b);
    }
    

注意:Lambda表达式只能简化函数式接口的匿名内部类的写法

12.标准的JavaBean类

  • 类名需要见名知意
  • 成员变量使用private修饰
  • 提供至少两个构造方法
    • 无参构造方法
    • 带全部参数的构造方法
  • 成员方法
    • 提供每一个成员变量对应的setXxx()/getXxx()
    • 如果还有其他行为,也需要写上

13.内部类

在一个类里面,再定义一个类,内部类表示的事物是外部类的一部分,内部类单独出现没有任何意义,比如:汽车的发动机,ArrayList的迭代器,人的心脏等等

  • 内部类的访问特点:可以直接访问外部类的成员,包括私有;外部类要访问内部类的成员,必须创建对象
13.1 匿名内部类

匿名内部类本质上就是隐藏了名字的内部类

new 类名或者接口名() {
	重写方法
};
//例如
new Inter(){
    public void show(){
    }
};

你可能感兴趣的:(Java学习,java,开发语言)