JavaEE 学习笔记 面向对象(下) 15

第六章 面向对象(下)


Java 面向对象学习的三条主线:
        Java 类及类的成员:属性,方法,构造器,代码块,内部类
        面向对象的三大特征:封装性,继承性,多态性,(抽象性)
        其他关键字:this,super,static,final,abstract,interface,import等      


6.6 模板方法设计模式(TemplateMethod)

        抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展,改造,但子类总体上会保留抽象类的行为方式。

        解决的问题:

                当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类实现。

                换句话说,在软件开发中实现一个算法时,整体步骤很固定,通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。


6.7 接口(interface)

6.7.1 接口的简述

        一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。另一方面,有时必须从几个类中抽取一些共同行为的特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标,键盘,打印机,扫描仪,摄像头,充电器,Mp3机,手机,数码相机,移动硬盘等都支持USB链接。

        接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个“是不是”的关系,而接口实现则是“能不能“的关系

        接口的本质是契约,标准,规范,就像我们法律一样。制定好后大家要遵守。

6.7.2 接口的使用

        接口使用interface来定义;Java中,接口和类是并列的两个结构;接口中不可以定义构造器,意味着接口不可以实现实例化;接口中能够定义的成员包括:抽象方法,全局常量,默认方法,静态方法;

        Java开发中,接口通过让类去实现(implements)的方式来使用,如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化,如果实现类没有覆盖接口中的所有抽象方法,则此实现类仍为一个抽象类。

        Java类可以实现多个接口,弥补Java单继承的局限性;接口与接口之间也可以继承,可以多继承。接口的具体使用,要实现多态性。

interface Person {

    public void Work();

}

interface Play {

    public void Kind();

}

//Java可以继承多个接口,消除了Java单继承的弊端
class Student implements Person,Play {

    @Override
    public void Work() {
        System.out.println("写作业");
    }

    @Override
    public void Kind() {
        System.out.println("打篮球");
    }
}

class Test {
    public static void main(String[] args) {
        Student s = new Student();
        s.Work();
        s.Kind();
    }
}

6.7.3 接口的应用:代理模式(Proxy)

       代理模式是Java开发中使用较多的一种设计模式。代理模式就是为其他对象提供一种代理以控制这个对象的访问。

        应用场景:

                ①.安全代理:屏蔽对真实角色的直接访问

                ②.远程代理:通过代理类处理远程方法调用(RMI)

                ③.延迟加载:先加载到轻量级的代理对象,真正需要再加载真实对象

        分类:静态代理:(静态定义代理类)

                  动态代理:(动态生成代理类)

import java.awt.*;
import javax.swing.*;
public class WySpecialtyProxy
{
    public static void main(String[] args)
    {
        SgProxy proxy=new SgProxy();
        proxy.display();
    }
}
//抽象主题:特产
interface Specialty
{
    void display();
}
//真实主题:婺源特产
class WySpecialty extends JFrame implements Specialty
{
    private static final long serialVersionUID=1L;
    public WySpecialty()
    {
        super("韶关代理婺源特产测试");
        this.setLayout(new GridLayout(1,1));
        JLabel l1=new JLabel(new ImageIcon("src/proxy/WuyuanSpecialty.jpg"));
        this.add(l1);   
        this.pack();       
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    }
    public void display()
    {
        this.setVisible(true);
    }
}
//代理:韶关代理
class SgProxy implements Specialty
{
    private WySpecialty realSubject=new WySpecialty();
    public void display()
    {
        preRequest();
        realSubject.display();
        postRequest();
    }
    public void preRequest()
    {
          System.out.println("韶关代理婺源特产开始。");
    }
    public void postRequest()
    {
          System.out.println("韶关代理婺源特产结束。");
    }
}

6.7.4 Java8中新特性

         Java8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。

        静态方法:使用static关键字修饰。可以通过接口直接调用静态方法,并执行其他方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。

        默认方法:默认方法使用default关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。比如:java 8 API中对Collection,List,Comparator等接口提供了丰富的默认方法。

6.7.5 Java8中关于接口的改进

                知识点1:接口中定义的静态方法,只能通过接口来调用

                知识点2:通过实现类的对象,可以调用接口中的默认方法,如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法

                知识点3:若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的抽象方法,则不会出现冲突问题。因此此时遵守:类优先原则。接口中具有相同名称和参数的默认方法会被忽略。

                知识点4:若一个接口中定义了一个默认方法,而另外一个接口也定义了一个同名同参数的方法(不管此方法是否是默认方法),在实现类同时实现了这两个接口时,会出现:接口冲突,解决办法:实现类必须覆盖接口中同名同参数的方法,来解决冲突

6.7.6 接口的练习

//CompareObject 接口
public interface CompareObject {
    //若返回为0,代表相等;若为正数代表当前对象大,若为负数代表当前对象小
    public int compareTo(Object o);

}
//Circle 类
public class Circle {
    private int redius;

    public Circle(int redius) {
        this.redius = redius;
    }

    public int getRedius() {
        return redius;
    }

    public void setRedius(int redius) {
        this.redius = redius;
    }
}
//ComparableCircle 类
public class ComparableCircle extends Circle implements CompareObject {

    public ComparableCircle(int redius) {
        super(redius);
    }

    @Override
    public int compareTo(Object o) {
        if (this == o) {
            return 0;
        }
        if (o instanceof ComparableCircle) {
            ComparableCircle c = (ComparableCircle) o;
            if (this.getRedius() > c.getRedius()) {
                return 1;
            } else if (this.getRedius() < c.getRedius()) {
                return -1;
            } else {
                return 0;
            }
        } else {
            return 0;
         }
    }
}
//InterfaceTest 实现类
public class InterfaceTest {
    public static void main(String[] args) {
        ComparableCircle circle1 = new ComparableCircle(2);
        ComparableCircle circle2 = new ComparableCircle(2);
        int i = circle1.compareTo(circle2);
        if (i == 0) {
            System.out.println("circle1 与 circle2 半径相等");
        } else if (i > 0) {
            System.out.println("circle1半径 比 circle2 半径大");
        } else if (i < 0) {
            System.out.println("circle1半径 比 circle2 半径小");
        }
    }

}

6.8 类的内部成员:内部类        

6.8.1 内部类的简述

        当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类;在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类;Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。 Inner class的名字不能与包含它的外部类类名相同。

        Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B成为外部类

6.8.2 内部类的分类

        成员内部类:(static成员内部类和非static成员内部类)(静态,非静态)

        局部内部类:(不谈修饰符),匿名内部类(方法内,代码块内,构造器内)

6.8.3 成员内部类

        ①.作为外部类的成员:可以调用外部类的结构,可以被static修饰,可以被4种不同的权限修饰

        ②.作为一个类:类内可以定义属性,方法,构造器等;可以被final修饰,表示此类不能被继承,言外之意,不使用final,就可以被继承;可以被abstract修饰

//测试类
public class Demo1 {
    public static void main(String[] args) {
        //实例化成员内部类
        //创建静态内部类的实例对象
        Person.Student student = new Person.Student();
        student.work();
        //创建非静态的成员内部类对象
        Person person = new Person();
        Person.Teacher teacher = person.new Teacher();
        teacher.work();
    }
}

class Person {

    //静态成员内部类
    static class Student {
        public void work(){
            System.out.println("听课");
        }
    }

    //非静态成员内部类
    class Teacher{
        private String name;
        private int age;

        public void work(){
            System.out.println("上课");
        };
    }

    public void play(){

        //局部内部类
        class StudentPlay{}
    }

    //代码块
    {
        //局部内部类
        class Eat{};
    }

}


点击进入:下一节:JavaEE 学习笔记 第七章 异常处理 16

猜你喜欢

转载自blog.csdn.net/woailuo8214/article/details/121316746
今日推荐