美文网首页
Java:抽象类&接口&内部类&Lambda

Java:抽象类&接口&内部类&Lambda

作者: iOS_修心 | 来源:发表于2023-05-14 10:52 被阅读0次

一.抽象类

抽象方法:

  • public abstract 返回值类型 方法名(参数列表);
    共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义为抽象方法

抽象类:

  • public abstract class 类名{}
    如果一个类中存在抽象方法,那么该类就必须声明为抽象类

抽象类特点

  • 抽象类不能实例化
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 可以有构造方法
    -抽象类的子类,要么重写抽象类中的所有抽象方法,要么还是抽象类
  • 动物类
public abstract class Animal {
    public void drink(){
        System.out.println("喝水");
    }

    public Animal(){

    }

    public abstract void eat();
}
  • 猫类
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
  • 狗类
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
}
  • 测试类
public static void main(String[] args) {
        Dog d = new Dog();
        d.eat();
        d.drink();

        Cat c = new Cat();
        c.eat();
        c.drink();
        //Animal a = new Animal();
        //a.eat();
    }
  • ``
狗吃肉
喝水
猫吃鱼
喝水

二.接口

当一个类中的所有方法都是抽象方法的时候,我们就可以将其定义为接口

1.声明

  • 接口用关键字interface来定义
    public interface 接口名 {}

  • 接口和类之间是实现关系,通过implements关键字表示
    public class 类名 implements 接口名 {}
    public class 类名 implements 接口名1 , 接口名2 {}

2.特点

  • 接口不能实例化

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

  • 成员变量 只能是常量�默认修饰符:public static final

  • 没有构造方法

  • 成员方法 只能是抽象方法, 默认修饰符:public abstract

JDK8版本后

  • 允许在接口中定义非抽象方法,但是需要使用关键字 default 修饰,这些方法就是默认方法
    作用:解决接口升级的问题
  • 接口中允许定义static静态方法
实例
  • 接口
public interface Inter {
    public static final int NUM = 10;

    public abstract void show();
}
  • 实现类
class InterImpl implements Inter{

    public void method(){
        // NUM = 20;
        System.out.println(NUM);
    }

    public void show(){

    }
}
  • 测试类
public class TestInterface {
    /*
        成员变量: 只能是常量 系统会默认加入三个关键字
                    public static final
        构造方法: 没有
        成员方法: 只能是抽象方法, 系统会默认加入两个关键字
                    public abstract
     */
    public static void main(String[] args) {
        System.out.println(Inter.NUM);
    }
  
}

类和接口的关系

  • 类和类的关系
    继承关系,只能单继承,但是可以多层继承
  • 类和接口的关系
    实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
  • 接口和接口的关系
    继承关系,可以单继承,也可以多继承

接口与父类冲突

  • 如果直接父类, 和接口中出现了相同的方法声明, 但是代码逻辑不一样,优先使用直接父类的代码逻辑.

三.内部类

在一个类中定义一个类。举例:在一个A类的内部定义一个B类, B类就被称为内部类

public class Outer {
     public class Inner {
     }  
}
内部类的访问特点
  • 内部类可以直接访问外部类的成员,包括私有对象
  • 外部类要访问内部类的成员,必须创建对象

成员内部类

将一个类,设计为内部类的目的,大多数都是不想让外界去访问,所以内部类的定义应该私有化,私有化之后,再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用。

   class Outer {
       private int num = 10;
       private class Inner {
           public void show() {
               System.out.println(num);
           }
       }
       public void method() {
           Inner i = new Inner();
           i.show();
       }
   }
   public class InnerDemo {
       public static void main(String[] args) {
           //Outer.Inner oi = new Outer().new Inner();
           //oi.show();
           Outer o = new Outer();
           o.method();
       }
   }

匿名内部类

是一个继承了该类或者实现了该接口的子类匿名对象

interface Inter{
    void method();
}

class Test{
    public static void main(String[] args){
        new Inter(){
            @Override
            public void method(){
                System.out.println("我是匿名内部类");
            }
        }.method(); // 直接调用方法
    }
}

匿名内部类在开发中的使用

当发现某个方法需要,接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码

/*
    游泳接口
 */
interface Swimming {
    void swim();
}

public class TestSwimming {
    public static void main(String[] args) {
        goSwimming(new Swimming() {
            @Override
            public void swim() {
                System.out.println("铁汁, 我们去游泳吧");
            }
        });
    }

    /**
     * 使用接口的方法
     */
    public static void goSwimming(Swimming swimming){
        /*
            Swimming swim = new Swimming() {
                @Override
                public void swim() {
                    System.out.println("铁汁, 我们去游泳吧");
                }
            }
         */
        swimming.swim();
    }
}

四:Lambda表达式

1.格式 :

  • (形式参数) -> {代码块}
  • 三要素形式参数,箭头,代码块
  • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
  • ->:由英文中画线和大于符号组成,固定写法。代表指向动作
  • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

2.使用前提

  • 有一个接口
  • 接口中有且仅有一个抽象方法
实例1:有参有返回值
interface Flyable {
   String fly(String s);
}

class FlyableDemo {
   public static void main(String[] args) {
       //在主方法中调用useFlyable方法
       //匿名内部类
       useFlyable(new Flyable() {
           @Override
           public String fly(String s) {
               s =  s + "晴空万里";
               System.out.println(s);
               return  s ;
           }
       });
       System.out.println("--------");

       //Lambda
       useFlyable((String s) -> {
           s =  "Lambda:" + s + "晴空万里";
           System.out.println(s);
           return s;
       });

   }

   private static void useFlyable(Flyable f) {
       f.fly("Override:风和日丽,");
   }
}
实例2:表达式的省略模式
interface Addable {
    int add(int x, int y);
}

interface Flyable {
    void fly(String s);
}

public class LambdaDemo {
    public static void main(String[] args) {
        // 1.参数的类型可以省略
//        useAddable((int x,int y) -> {
//            return x + y;
//        });
        useAddable((x, y) -> {
            return x + y;
        });

//        useFlyable((String s) -> {
//            System.out.println(s);
//        });
        //2.如果参数有且仅有一个,那么小括号可以省略
//        useFlyable(s -> {
//            System.out.println(s);
//        });

        //3.如果代码块的语句只有一条,可以省略大括号和分号
        useFlyable(s -> System.out.println(s));

        //4.如果代码块的语句只有一条,可以省略大括号和分号,如果有return,return也要省略掉
        useAddable((x, y) -> x + y);
    }
    //接口的实现
    private static void useFlyable(Flyable f) {
        f.fly("风和日丽,晴空万里");
    }

    private static void useAddable(Addable a) {
        int sum = a.add(10, 20);
        System.out.println(sum);
    }
}

3.Lambda表达式和匿名内部类的区别

  • 所需类型不同
    匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
    Lambda表达式:只能是接口

  • 使用限制不同
    1: 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
    2: 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式

  • 实现原理不同
    匿名内部类:编译之后,产生一个单独的.class字节码文件
    Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

相关文章

  • Java 接口知识点

    接口的特性 函数式接口 抽象类和接口区别 Lambda表达式 java常用接口

  • 知识点总结

    1. java: * 集合 * 内部类,匿名类,静态类 * 抽象类,接口区别 * 线程池 * ...

  • java8之一——lambda表达式

    一、lambda 1、匿名内部类 2、lambda与函数式接口 Java 8增加了一种特殊的注解@Function...

  • Lambda表达式-03-02

    外部类实现线程接口: 内部类实现线程接口: 匿名内部类: jdk8的Lambda表达式:

  • 16. 对象声明与伴生对象

    匿名内部类 匿名内部类主要是针对那些获取抽象类或者接口对象而来的。最常见的匿名内部类点击事件: 上面这个是Java...

  • Android面试复习

    一.Java基础 1.Java语法关键字:接口和抽象类,反射,内部类,字符串,范型,枚举,引用类型,注解,NIO,...

  • Java面试核心框架

    常量池 常用关键字 final static 内部类 抽象类 接口 异常 注解 容器 内存管理内存模型、工作内...

  • 接口,抽象类,工厂设计模式,代理模式

    一、接口的结构: 抽象方法 全局常量 最终写法: 其他内部结构内部类内部抽象类内部接口 二、接口和抽象类 抽象类可...

  • Java匿名内部类

    导语 学完匿名内部类就懂的情书。 主要内容 接口与抽象类和匿名内部类的关系 具体内容 匿名内部类也就是没有名字的内...

  • PHP转JAVA的记录

    Java 数组 内部类 内部类的创建:内部类可以对包内其他类隐藏想实现一个接口时, 不想新建类文件 内部类可以访问...

网友评论

      本文标题:Java:抽象类&接口&内部类&Lambda

      本文链接:https://www.haomeiwen.com/subject/yfpjsdtx.html