Java学习_抽象类、接口、内部类_2014_1_16

****************************************************************************************************************
日期:2015年 1月 16日
主题:抽象类、接口、内部类
相关文件夹:第五章_高级类特性2
****************************************************************************************************************
内容:
一、抽象类
在抽象类中只能有抽象方法不能有抽象属性,抽象方法不需要有具体的方法体,具体方法必须在子类中去实现。
    *抽象类不能被实例化,但是可以定义构造器,有参无参都行,并在子类对象中去执行,可以通过运行时多态将其实例
化(即类的多态)。
    *能不继承尽量别继承。
    *含有抽象方法的类必须被声明为抽象类。
    *在子类中具体是不需要加abstract关键字。
什么时候用抽象类,什么时候用接口。
    *抽象类不能被final修饰:因为抽象类需要被继承。
    *不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法。
    例
    abstract class A{   
        abstract void m1( );
        public void m2( ){
        System.out.println("A类中定义的m2方法");
        }
    }

    class B extends A{
        void m1( ){
         System.out.println("B类中定义的m1方法");
        }
    }

    public class Test{
        public static void main( String args[ ] ){
         A a = new B( );
         a.m1( );
         a.m2( );
        }
    }
1.System.currentTimeMillis()返回当前时间的秒数,取得是系统时间。
2.模板方法设计模式(TemplateMehod)
    抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,
但子类总体上会保留抽象类的行为方式。
    解决的问题:
    ①当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
    ②编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。
    例:(取时间,或者代码的执行时间。)
    abstract class Template{
    public final void getTime(){
        long start = System.currentTimeMillis();
        code();
        long end = System.currentTimeMillis();
        System.out.println("执行时间是:"+(end - start));
    }
    public abstract void code();
    }
    class SubTemplate extends Template{
        public void code(){
            for(int i = 0;i<10000;i++){
            System.out.println(i);
    } } }
****************************************************************************************************************
二、更彻底的抽象:接口(interface)
1.接口的基本内容:
    *接口中的属性只能是公有的不能是私有个的。
    *接口中的方法不能有实现,但是不需要加abstract关键字。
    *****接口可以继承别的接口,且可多继承***接口可以多继承,类是单继承的。
    *使用接口的关键字implements。
    *增删改查CRUD
    *接口是不能new的,只能new它的实现类。
    *通常接口中的变量都是常量:public static final int age = 0;
    *****在使用接口的类中也可以继承其他的类,先继承后实现接口。
    见下例:
    package com.interface1;

    public interface Dao {

        public void Query();
        public void Update();
    }
    

    package com.interface1;

    public interface Delete {

        public void Delete();
    }


    package com.interface1;

    public interface Person extends Dao,Delete {
        public static final int age = 0;
        public void add();
    }


    package com.interface1;

    public class PersonImpl implements Person,Dao {

    @Override
    public void Query() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void Update() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void Delete() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void add() {
        // TODO Auto-generated method stub
        
    }

    }
2.工厂模式(针对接口的):
    概述:
    定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。
    适用性:
    ①当一个类不知道它所必须创建的对象的类的时候
    ②当一个类希望由它的子类来指定它所创建的对象的时候
    ③当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
    例子:
    package com.interface1;

    public interface IWorkFactory {

        public Work getWork();
    
    }

    package com.interface1;

    public class StudentWorkFactory implements IWorkFactory{
    
        @Override
        public Work getWork() {
            // TODO Auto-generated method stub
            return new StudentWork();
        }
    
    }

    package com.interface1;

    public class TeacherWorkFactory implements IWorkFactory{

        @Override
        public Work getWork() {
            // TODO Auto-generated method stub
            return new TeacherWork();
        }
    
    }
    
    package com.interface1;

    public class StudentWork implements Work{

        @Override
        public void doWork() {
            System.out.println("学生工作");
        }

    }

    package com.interface1;

    public class TeacherWork implements Work{

        @Override
        public void doWork() {
            // TODO Auto-generated method stub
            System.out.println("老师工作");
        }

    }
    
    package com.interface1;

    import org.junit.Test;

    public class Testing {

        @Test
        public void test1() {
            TeacherWorkFactory twf = new TeacherWorkFactory();
            TeacherWork tw = null;
            StudentWork sw = null;
            StudentWorkFactory swf = new StudentWorkFactory();
            for (int i = 0; i < 10; i++) {
                tw = (TeacherWork) twf.getWork();
                tw.doWork();
                System.out.println(tw);
            }
            for (int i = 0; i < 10; i++) {
                sw = (StudentWork) swf.getWork();
                sw.doWork();
                System.out.println(swf.getWork());
            }
        }
    }

    总结:
        FactoryMethod模式是设计模式中应用最为广泛的模式,在面向对象的编程中,对象的创建工作非常简单,对象的创
    建时机却很重要。FactoryMethod解决的就是这个问题,它通过面向对象的手法,将所要创建的具体对象的创建工作
    延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。
3.代理模式:
概述:
为其他对象提供一种代理以控制对这个对象的访问。

    package com.interface1;

    public interface Object {

        public void action();
    
    }

    
    package com.interface1;

    public class ObjectImpl implements Object {

        @Override
        public void action() {
            // TODO Auto-generated method stub
            System.out.println("======");
            System.out.println("======");
            System.out.println("被代理的类");
            System.out.println("======");
            System.out.println("======");
        }
    
    }

    package com.interface1;

    public class ProxyObject implements Object {
    
        Object obj;
    
        public ProxyObject(){
            System.out.println("这是代理类");
            obj = new ObjectImpl();
            }
    
        @Override
        public void action() {
            // TODO Auto-generated method stub
            System.out.println("代理开始");
            obj.action();
            System.out.println("代理结束");
        }

    }    

总结:
在开发中,一个类不要去继承一个已经实现好的类,要么继承抽象类,要么实现接口。
通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。
接口主要用来定义规范。解除耦合关系。
Java也可以说是一种面向接口的编程方式。(JDBC也相当于一种接口)

练习:
定义一个接口用来实现两个对象的比较。
interface CompareObject{
    public int compareTo(Object o);   //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
 }
定义一个Circle类。
定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。在ComparableCircle类中给出接口中方法compareTo
的实现体,用来比较两个圆的半径大小。
定义一个测试类TestInterface,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
思考:参照上述做法定义矩形类Rectangle和ComparableRectangle类,在ComparableRectangle类中给出compareTo方法的实现,
比较两个矩形的面积大小。
代码:
package com.interface1;

public class Circle {

    private double radius;

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
}

package com.interface1;

public class ComparableCircle extends Circle implements CompareObject {

    @Override
    public int compareTo(Object o) {
        Circle c = (Circle) o;
        int ans = 0;
        if (this.getRadius() == c.getRadius())
            ans = 0;
        else if (this.getRadius() > c.getRadius())
            ans = 1;
        else
            ans = -1;

        switch (ans) {
        case 1:
            System.out.println("第一个圆大");
            break;
        case 0:
            System.out.println("两个圆一样大");
            break;
        case -1:
            System.out.println("第二个圆大");
            break;
        default:
            System.out.println("比较出错");
            break;
        }
        return ans;
    }

}

package com.interface1;

import org.junit.Test;

public class Testing {

    @Test
    public void test1() {
        TeacherWorkFactory twf = new TeacherWorkFactory();
        TeacherWork tw = null;
        StudentWork sw = null;
        StudentWorkFactory swf = new StudentWorkFactory();
        for (int i = 0; i < 10; i++) {
            tw = (TeacherWork) twf.getWork();
            tw.doWork();
            System.out.println(tw);
        }
        for (int i = 0; i < 10; i++) {
            sw = (StudentWork) swf.getWork();
            sw.doWork();
            System.out.println(swf.getWork());
        }
    }
    

    @Test
    public void TestInterface()
    {
        ComparableCircle cc1 = new ComparableCircle();
        cc1.setRadius(30);
        System.out.println(cc1.getRadius());
        ComparableCircle cc2 = new ComparableCircle();
        cc2.setRadius(60);
        System.out.println(cc2.getRadius());
        cc1.compareTo((Object)cc2);
    
    }
    
}

    
****************************************************************************************************************
三、类的成员之五:内部类
    1.分类:
    成员内部类(static成员内部类和非static成员内部类)
    局部内部类(不谈修饰符)、匿名内部类(在方法中)
    *Inner class可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访
    问内部类中的成员需要:内部类.成员或者内部类对象.成员。
    *Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
    Inner class的名字不能与包含它的类名相同;
    *在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。
    2.例子:
    public class A{
        private int s = 111;
        public class B {
    private int s = 222;
    public void mb(int s) {
            System.out.println(s);              // 局部变量s
            System.out.println(this.s);      // 内部类对象的属性s
            System.out.println(A.this.s);   // 外层类对象属性s
    }
       }
       public static void main(String args[]){
    A a = new A();
    A.B b = a.new B();
    b.mb(333);
        }}
    3.内部类的特性
    *Inner class作为类的成员:
    可以声明为final的
    和外部类不同,Inner class可声明为private或protected;
    Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;
    *Inner class作为类:
    可以声明为abstract类 ,因此可以被其它的内部类继承
    *非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员。
****************************************************************************************************************
四、匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含
实现一个接口或实现一个类。

    new 父类构造器(实参列表)|实现接口(){
        //匿名内部类的类体部分
    }
    例子:
    interface  A{
        public  abstract void fun1();
    }
    public class Outer{
        public static void main(String[] args) {
            new Outer().callInner(new A(){
                   //接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
                public void fun1() {
                    System.out.println(“implement for fun1");
                }
            });// 两步写成一步了
        }
        public void callInner(A a) {
            a.fun1();
        }
    }  
    例2:
    package com.oracle.InnerClass;
    
    public class Test {
    
        public Test() {
            Inner s1 = new Inner();
            s1.a = 10;
            Inner s2 = new Inner();
            s2.a = 20;
            Test.Inner s3 = new Test.Inner();
            System.out.println(s3.a);
       }
        class Inner {
            public int a = 5;
       }

       public static void main(String[] args) {
            Test t = new Test();
            Inner r = t.new Inner();
            System.out.println(r.a);
           }
    

    }
    结果:
    5
    5
****************************************************************************************************************
其他内容
||和|的区别是:||当前面的对了之后直接返回TRUE不再执行后面语句,|则要两条语句都执行。
&&和&的区别类似。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值