多态、接口、内部类

面向对象高级

 

 多态

在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;

 

接口(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();

}

 

 

 

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/Djw168888/article/details/81158405