记录我的java之路——day8(周更)

day8-面向对象高级

  • 多态

  • 接口

  • 内部类

多态

在java中,方法和属性都是可以以多态的形式存在的,方法的多态主要体现方法的重写与重载;属性的多态一般表现形式为父类引用指向子类对象(向上转型);一个引用类型变量既可以指向该引用类型自身,也可以指向该类型子对象,该操作称之为多态,或者动态绑定。

public abstract class Animal{
    public abstract void sleep();
} 
​
public class Dog extends Animal{
    public void sleep(){
        System.out.println("呼呼大睡。。。。");
    }
}
​
public class Test{
    public static void main(String[] args){
        //父类引用指向子类对象
        Animal a = new Dog();
    }
}

多态的优势:

  1. 降低了类之间的耦合

  2. 面向抽象编程

  3. 提高程序的可扩展性

多态中关于对象转型问题:

可以使用父类引用指向子类对象(上转型);反过来子类引用可以指向父类对象(下转型),但是被下转型的父类对象原本就应该是子类的对象,否则会出现:java.lang.ClassCastException异常(造型失败)

//上转型
Animal a = new Dog("旺财");
​
Dog dog = (Dog)new Animal(); //java.lang.ClassCastException
​
//下转型
Dog d = (Dog)a;
扫描二维码关注公众号,回复: 2733634 查看本文章

接口(interface)

interface,是一种比抽象类更纯粹的结构,接口中只能存在抽象方法和常量(接口是一组抽象方法和常量的集合),接口并不是类,所以没有构造器;一般可以由具体类对接口进行实现,并且具体类必须实现接口中的所有方法

接口语法:

<modifier> interface <name>[extends <superinterface>] {

​ <attribute_declarations> <method_declarations>

}

接口(Flyable.java):

interface Flyable{
    //常量定义(系统自动补充:public static final String TYPE = "bird")
    String TYPE = "bird";
    //抽象方法定义(系统自动补充:public abstract void fly())    
    void fly();
}

实现类(Bird.java):

class Bird implements Flyable{
    
    public void fly(){
        System.out.println("自由自在翱翔天际!");
    }
}

以上为一个标准接口的定义以及实现类对接口的具体实现,在java中实现类还可以实现多个接口以弥补类只能单继承的缺陷,例如还有一个接口Singable,里面包含一个sing方法,此时实现类除了实现Flyable接口外还能实现Singable接口,但是实现类必须对所有接口的方法进行实现,如下:

接口2(Singable):

interface Singable{
    
    public void sing();
}

实现类(Bird.java)

class Bird implements Flyable,Singable{
    
    public void fly(){
        System.out.println("自由自在翱翔天际!");
    }
    
    public void sing(){
        System.out.println("你是我的小呀小苹果~~");
    }
}

接口与抽象类的区别

  1. 接口是一种更纯粹的抽象结构

  2. 接口是对行为的抽象(接口描述动词),抽象类是对一些类型的抽象(抽象类描述名词)

  3. 一个类只能存在一个直接父类,但是类可以实现多个接口(实现类必须实现所有的方法)

  4. 接口可以继承接口,并且能同时继承多个接口,抽象类只能直接继承一个抽象类

内部类

java中可以在一个类的内部定义属于该类的从属类,从属类具备访问外部类的成员的能力,内部类提供了比方法更完整封装性,内部类主要包含以下几种:

  1. 成员内部类

  2. 局部内部类

  3. 静态内部类

  4. 匿名内部类

成员内部类

public class Outter {
​
    private String name = "旺财";
    
    public void m1(){
        InnerClass1 ic = new InnerClass1();
        System.out.println("获取内部类的成员变量:"+ic.name2);
    }
    
    /**
     * 成员内部类
     * @author mrchai
     *
     */
    private class InnerClass1{
        private String name2 = "来福";
        
        public void m2(){
            //内部类可以直接使用外部类的成员变量与方法
            System.out.println("成员内部类的方法:"+name);
            Outter.this.m1();
        }
        
        public void m1(){
            System.out.println("内部类的m1方法");
        }
    }
    
    public static void main(String[] args) {
        Outter.InnerClass1 in = new Outter().new InnerClass1();
        in.m2();
    }
}

局部内部类

public class Outter2 {
​
    private String name = "旺财";
    
    public void m(){
        //局部变量如果在内部类中使用则必须使用final修饰
        final int i = 10;
        //局部内部类不允许使用访问修饰符修饰
        class Inner{
            public void m2(){
                System.out.println("hello,局部内部类:"+i);
            }
        }
        //局部内部类的访问仅限于声明区域
        new Inner().m2();
    }
    
}

静态内部类

public class Outer3 {
​
    private String name1 = "旺财";
    
    static class Inner{
        String name2 = "来福";
        
        public void m(){
            System.out.println("外部类的成员变量:"+new Outer3().name1);
        }
    }
    
    public void m2(){
        new Inner().m();
    }
    
    public static void main(String[] args) {
        Outer3.Inner in = new Outer3.Inner();
        in.m();
    }
}
​

匿名内部类

匿名内部类顾名思义,即没有名字的内部类,一般表现形式为使用父类的引用指向你一个匿名对象,方法的实现在匿名语句块中完成

Animal a = new Animal() {
    @Override
    public void sleep() {
        System.out.println("休眠一下");
    }
};
//输出地址非Animal对象,而是包含了“$”符号的对象地址(即内部类)
System.out.println(a);
a.sleep();
​
Cat c = new Cat(){
    @Override
    public void eat() {
        System.out.println("吃猫粮");
    }
};
/*
针对以下接口创建匿名内部类对象
interface Sportable{
    void run();
    void jump();
}
*/

匿名内部类与回调机制

Button.java

public class Button {
​
    //内部接口
    public interface OnClickListener{
        //回调函数(钩子函数)
        void click();
    } 
    
    public void setOnClickListener(OnClickListener lis){
        System.out.println("准备触发");
        lis.click();
        System.out.println("清理资源");
    }
}

ButtonTest.java

public class ButtonTest{
    public static void main(String[] args) {
​
        Button btn = new Button();
        //匿名内部类使用
        btn.setOnClickListener(new OnClickListener() {
            //回调机制
            @Override
            public void click() {
                System.out.println("事件被触发。。。。");
            }
        });
    }
}   

关于内部类注意事项

  1. 内部类可以使用外部类的成员变量和方法

  2. 局部内部类如果需要使用外部方法(或者语句块)的局部变量,该局部变量必须使用final修饰(延长局部变量的生命周期)

  3. 局部内部类的使用范围仅限于声明区域

  4. 静态内部类中不能直接使用外部类的实例方法实例变量,创建外部类对象,才能通过对象调用

猜你喜欢

转载自blog.csdn.net/qq_34304871/article/details/81159632
今日推荐