黑马程序员技术交流社区

标题: 抽象类和接口的问题? [打印本页]

作者: 黑马-胡占朝    时间: 2011-7-28 01:59
标题: 抽象类和接口的问题?
1.接口中可以有构造方法吗?
2.抽象类和接口是不是都可以有静态成员变量?
3.抽象类和接口在具体应用的方向?
作者: 詹季春    时间: 2011-7-28 02:38
问题一:因为接口是一种特殊的“抽象类”,并且接口里面定义的是一种规范,所以接口里面不能包含构造器也不能包含初始化定义,但是可以包含属性(只能是常量)、方法(只能是抽象方法)、内部类(包括接口)和枚举类定义;
问题二:抽象类允许定义静态成员变量也可以定义普通的成员变量;接口里面只能定义静态常量属性,不能定义普通属性
原因:因为对于接口而言,里面定义的常量属性是和接口相关的,而且只能是常量,所以系统会自动为这些属性添加static和final修饰符,不管拟定于接口有没有使用,系统都会默认为public static final修饰如下[code=java]int MAX_SIZE = 50 ;
public static final int MAX_SIZE = 50 ;[/code]以上两个效果是一样的

问题三:抽象类的实际应用方向-->模板设计
定义抽象类Person[code=java]package cn.itcast.heima
public abstract class Person{      //定义抽象类Person

      private String name;          //定义name属性
       private int age;               //定义age属性

       public Person(String name,int age){            //为属性初始化
              this.name = name;                        //为name属性赋值
              this.age = age;                          //为age属性赋值

       }

       public String getName(){                       //取得name属性内容
              return name;
       }

       public int getAge(){                           //取得age属性内容
              return age;
       }

       public void say(){                               //说话是具体功能,要定义成普通方法
              System.out.println(this.getContent());
       }
       public abstract String getContent();      //说话内容由子类定义
}[/code]定义Student继承Person类[code=java]package cn.itcast.heima
public class Student extends Person{            //定义Student继承Person类
       private float score;                              
       public Student(String name,int age,float score){
            super(name,age);                                //调用父类中构造方法
              this.score = score;         
       }

       public String getContent(){                         //覆写父类中的抽象方法
              return "Student 信息-->姓名:"+super.getName()+
                            ",年龄:"+super.getAge()
                            +",score:"+this.score;
       }
}[/code]定义Worker继承Person类[code=java]package cn.itcast.heima
public class Worker extends Person{                           //定义Worker继承Person类
       private float salary;
       public Worker(String name,int age,float salary){  
            super(name,age);                                //调用父类中构造方法
              this.salary = salary;
       }

       public String getContent(){                         //覆写父类中的抽象方法
              return "Worker 信息-->姓名:"+super.getName()+
                            ",年龄:"+super.getAge()
                            +",salary:"+this.salary;
       }
}[/code]定义测试类[code=java]package cn.itcast.heima
public class Demo{
       public static void main(String args[]){
            Person student = null;   
              Person worker = null;                 
              student = new Student("老罗",15,30.0f);  
              worker = new Worker("小罗",14,20.0f);     
              student.say();                                       
              worker.say();                                               

       }
}[/code]-------------------------------------------------------------------------------------
接口的实际应用方向-->制定系统各模块应该遵循的标准例如简单的工厂模式
定义一个接口、作为输出设备参考[code=java]package cn.itcast.heima;
public interface Output
{
        //接口里定义的属性只能是常量
        int MAX_CACHE_LINE = 50;
        //接口里定义的只能是public的抽象实例方法
        void out();
        void getData(String msg);
}[/code]定义Computer用来最后决定使用那种方式打印[code=java]package cn.itcast.heima;

public class Computer
{
        private Output out;

        public Computer(Output out)
        {
                this.out = out;
        }
        //定义一个模拟获取字符串输入的方法
        public void keyIn(String msg)
        {
                out.getData(msg);
        }
        //定义一个模拟打印的方法
        public void print()
        {
                out.out();
        }
}code]
定义一个Output工厂来生产Output对象
[code=java]package cn.itcast.heima;
public class OutputFactory
{
        public Output getOutput()
        {
                //下面两行代码用于控制系统到底使用Output的哪个实现类。
                //return new Printer();
                return new BetterPrinter();
        }
        public static void main(String[] args)
        {
                OutputFactory of = new OutputFactory();
                Computer c = new Computer(of.getOutput());
                c.keyIn("中关村黑马程序员训练营");
                c.keyIn("黑马程序员训练营学业就业薪水曝光:平均7K");
                c.print();
        }
}[/code]下面定义两种打印方式:Printer[code=java]package cn.itcast.heima;
public class Printer implements Output
{
        private String[] printData = new String[MAX_CACHE_LINE];
        //用以记录当前需打印的数据份数
        private int dataNum = 0;
        public void out()
        {
                //只要还有数据,继续打印
                while(dataNum > 0)
                {
                        System.out.println("打印机打印:" + printData[0]);
                        //把数据队列整体前移一位,并将剩下的数据数减1
                        System.arraycopy(printData , 1, printData, 0, --dataNum);
                }
        }
        public void getData(String msg)
        {
                if (dataNum >= MAX_CACHE_LINE)
                {
                        System.out.println("输出队列已满,添加失败");
                }
                else
                {
                        //把打印数据添加到队列里,已保存数据的数量加1。
                        printData[dataNum++] = msg;
                }
        }

}[/code]BetterPrinter[code=java]package cn.itcast.heima;

public class BetterPrinter implements Output
{
        private String[] printData = new String[MAX_CACHE_LINE * 2];
        //用以记录当前需打印的数据份数
        private int dataNum = 0;
        public void out()
        {
                //只要还有数据,继续打印
                while(dataNum > 0)
                {
                        System.out.println("高速打印机正在打印:" + printData[0]);
                        //把数据队列整体前移一位,并将剩下的数据数减1
                        System.arraycopy(printData , 1, printData, 0, --dataNum);
                }
        }
        public void getData(String msg)
        {
                if (dataNum >= MAX_CACHE_LINE * 2)
                {
                        System.out.println("输出队列已满,添加失败");
                }
                else
                {
                        //把打印数据添加到队列里,已保存数据的数量加1。
                        printData[dataNum++] = msg;
                }
        }
}[/code]--------------------------------------------------
最后我们总结一下接口和抽象类的区别
1、接口里面只能包含抽象的方法,不包含已经提供实现的方法;
   抽象类则完全可以包含普通方法
2、接口里不能定义静态方法;
   抽象类里可以定义静态方法
3、接口里只能定义静态常量属性,不能定义普通属性
   抽象类里则既能定义普通的属性,也能定义静态常量属性,
4、接口不包含构造器,
   抽象类里可以包含构造器,抽象类里的构造器并不是用来创建对象的,而是让他的子类来调用这些构造器来完成属于抽象类的初始化操作
5、接口里不能包含初始化模块
   抽象类里面则完全可以包含初始化模块
6、一个类最多只能有一个直接父类,包括抽象类,
   但是一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足
[ 本帖最后由 詹季春 于 2011-07-28  02:56 编辑 ]
作者: 杨志罡    时间: 2011-7-28 03:54
顶楼上,只能在这里善心悦目然后拉车往前赶了,希望哪天也能代码如此犀利
[ 本帖最后由 杨志罡 于 2011-07-28  04:03 编辑 ]




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2