栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

12抽象类与接口

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

12抽象类与接口

1、抽象类

这个更注重于是不是

例如小狗是动物,那么小狗就继承父抽象类动物,再比如:黑白打印机是打印机,那么黑白打印机就继承抽象类打印机。

一个类中如果存在抽象方法,那么他必须是抽象类

抽象类VS普通类

抽象类不能被直接实例化,但是可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例

普通类可以被实例化

抽象类中可以存在抽象方法,普通类中不能有抽象方法

世界上并不存在一个单纯是动物的东西,动物是一个抽象的集合,你只能说狗是动物,猫是动物,但是你没法真的实例化一个“动物”,所以动物就是抽象类。打印机也是如此,黑白打印机是打印机,你可以实例化一个黑白打印机,但一般不会去实例化“打印机”。

“你是人,我是人,但没有’人是人’“

    //抽象方法打印
    public abstract class Printer{
        public abstract void print();
    }
    //重写打印方法的彩色打印机类
    public class CPrinter extends Printer{
        @Override
        public void print(){
            System.out.println("这是一个彩色打印机,打印了彩色的文件");
        }
    }
    //重写打印方法的黑白打印机类
    public class BWPrinter extends Printer{
        @Override
        public void print(){
            System.out.println("这是一个黑白打印机,他打印了一张黑白图片");
        }
    }

    //测试类
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        while (true){
            System.out.println("请问你要选择什么打印机? 1、黑白打印机 2、彩色打印机");
            int flag = input.nextInt();
            Printer printer;
            if (1==flag){
                printer = new BWPrinter();
            }else {
                printer = new CPrinter();
            }
            printer.print();
            System.out.println("=========================================");
        }
    }

抽象类中可以没有抽象方法,但包含了抽象方法的类必须被定义为抽象类

如果子类没有实现父类的所有抽象方法,子类必须被定义为抽象类

没有抽象构造方法,也没有抽象静态方法

抽象类中可以有非抽象的构造方法,创建子类的实例时可能调用

2、接口

注重于能不能(功能)?

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

接口是一种"引用数据类型",编译之后也是class文件

接口是完全抽象,接口不能被实例化,(不过让子类重写抽象方法后就可以使用)

接口定义:

public interface Xxx{
    
}

接口中只支持共有的静态常量+共有抽象方法(共有的即public)

接口中所有的元素都是public关键字修饰的

接口中变量默认被public static final修饰,(相当于常量,变量名要全大写)

接口中的抽象方法的public abstract可以省略(抽象方法没有方法体,即 public abstract void 方法名();)

接口支持多继承,并且接口只可以继承接口

public interface Xxx extends A,B{
    
}

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

public class 类名 implements 接口名{}

此时上面这个就是接口的子类,或者说实现类,它只有两个选择,要么重写接口中的所有抽象方法,要么被定义为抽象类,这个子类也可以继承多个接口,但是必须把所有抽象方法全部重写

接口的两个意义:

规则的定义

程序的扩展性

接口没有构造方法,但是子类中可以使用super(),因为所有的类都直接或者间接的继承了Object

接口的成员变量:只能是常量,系统会默认加上public static final

接口的成员方法:只能是抽象方法,系统会默认加上public abstract

2、1JDk8以后的新特性

允许在接口中定义非抽象方法(即带有方法体),但是需要使用default修饰,即默认方法,用来解决接口升级的问题

默认方法的定义格式:

public default 返回值类型 方法名(参数列表){}

默认方法不是抽象方法,实现时,不强制要求重写,但是重写时必须去掉default关键字

实现多个接口时,若存在同名默认方法,就必须重写。

允许在接口中定义static静态方法

静态方法定义格式:

public static 返回值类型 方法名(参数列表){}

静态方法只能通过接口名调用,不能通过实现类类名或者对象名调用,也因此实现多个接口,且里面有重名静态方法时,不会报错

public可以省略,static不可以

JDK9中可以存在私有方法

2、2类和接口的关系

类和类:

继承关系,只能单继承,但可以多级继承

类和接口:

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

接口和接口:

继承关系,可以单继承,也可以多继承

3、面向对象的设计原则

多用组合,少用继承

针对接口编程

针对扩展开放,针对改变关闭

4、内部类

在一个类中定义一个类,例如A类中定义B类,那么B类就是内部类

public class Demo{
    public static void main(String[] args){
        
        Outer.Inner i = new Outer().new Inner();
        System.out.println(i.num);
        i.show();
    }
}

class Outer{
    
    Private int a =  10;
    
    class Inner{
        int num = 10;
        public void show(){
            System.out.println("Inner...show");
            //内部类可以直接访问外部类成员,包括私有
            System.out.println(a);
        }
    }
}

外部类要想访问内部类成员,就必须创建对象

按照内部类在类中定义的位置不同,可以分为以下两种形式:

在类的成员位置:成员内部类

在类的局部位置:局部内部类

4、1成员内部类

成员内部类也是成员,也就可以被一些修饰符修饰例如(private static)

private:

私有成员内部类访问:在自己所在的外部类中创建对象访问

public class Demo{
    public static void main(String[] args){
        
        Outer o = new Outer();
        o.method();
    }
}

class Outer{
    
   private class Inner{
        
        public void show(){
            System.out.println("Inner...show");   
        }
       public void method(){
           Inner i = new Inner();
           i.show
       }
    }
}

static:

静态成员内部类访问格式:

外部类名.内部类名 对象名 = new 外部类名.内部类名();
public class Demo{
    public static void main(String[] args){
        //外部类名.内部类名 对象名 = new 外部类名.内部类名();
        Outer.Inner oi = new Outer.Inner();
        oi.show();
        //被static修饰的成员,属于它的类,所以可以一路类名.下去
        Outer.Inner.method();
    }
}

class Outer{
  
     static class Inner{
  
        public void show(){
            System.out.println("Inner...show");
        }
         public static void method(){
             System.out.println("Inner...method");
         }
    }
}
4、2局部内部类

局部内部类是在方法中定义的类,外界是无法直接使用的,需要在方法内部创建对象并使用,该类可以直接访问外部类的成员,也可以访问方法内的局部变量

public class Demo{
    
    public static void main(String[] args){
       Outer o = new Outer();
        o.method
    }
}

class Outer{
    int a =10;
  
    public static void method(){
    
        int b =20;
      class Inner{
  
        public void show(){
            System.out.println("show....");
            System.out.println(a);
            System.out.println(b);
        }   
      }
      Inner i = new Inner();
        i.show();
    }
}
4、3匿名内部类

本质上是一个特殊的局部内部类(定义在方法内部)

匿名内部类就是将继承/实现,方法重写,创建对象放在一步进行

前提条件:需要存在一个接口或者类

格式:

new 类名或者接口名(){
重写方法;
};

在此之前如果要使用一个接口的方法

1、创建实现类,通过implements关键字去实现接口

2、重写方法

3、创建实现类对象

4、调用重写后的方法

public class Test {    
public static void main(String[] args) {
    InterImpl ii = new InterImpl();
    ii.show();
    }
}

interface Inter{
    void show();
}

class InterImpl implements Inter{
    @Override
    public void show(){
        System.out.println("InterImpl  重写的show方法")  
    }
}

用了匿名内部类之后简化为:

public class Test {    
public static void main(String[] args) {
     new Inter(){
         @Override
         public void show(){
             System.out.println("匿名内部类中的show方法")  
         }
     }.show();
}

interface Inter{
    void show();
}

匿名内部类就是将继承/实现,方法重写,创建对象放在一步进行

如果一个接口中有多个方法

public class Test {    
public static void main(String[] args) {
    //父类引用指向子类对象——多态
    Inter i = new Inter(){
         @Override
         public void show1(){
             System.out.println("匿名内部类中的show1方法")  
         }
         @Override
         public void show2(){
             System.out.println("匿名内部类中的show2方法")  
         }
     };
        i.show1();
        i.show2(); 
}

interface Inter{
    void show1();
    void show2();
}

匿名内部类的使用场景:当方法的形式参数为接口或者抽象类时,可以将匿名内部类作为实际参数进行传递

5、箭头函数Lambda表达式
    public interface HardDisk {
        String getCapacity();
    }

    public class Test {
        public static void main(String[] args) {
            //Lambda表达式  箭头函数
            //首先如果我们的一个类为只有一个方法的类
            //那么我们使用匿名内部类时
            //可以使用以下方法实现,将参数写在第一个位置,之后跟上一个箭头,接着是大括号,写代码
            HardDisk hardDisk = () -> {
                return "400GB";
            };
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/946437.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号