抽象类

  1 抽象类:普通类中添加抽象方法,不能实例化,【向上转型】之后实例化
  2         一定要(非抽象类的)子类覆写抽象类(父类)中●全部●的抽象方法【强制子类重写】
  3     ★★★强制规定了子类必须要做的事情,可以与自身的普通方法配合★★★
  4     ★缺点:单继承局限★
  5 普通类:可以直接产生实例化对象,可以包含构造方法、普通方法、static方法、常量、变量的内容
  6 
  7 抽象方法:没有{},同时使用关键字abstract进行定义
  8 抽象方法一定在抽象类(一定要使用abstract声明)中,抽象类中可以不要抽象方法
  9 
 10 范例:
 11 【class文件名和public对应的类名是一样的,class文件只能有一个public】
 12 /**
 13  * 父类
 14  */
 15 public abstract class B {
 16     /**
 17      * 普通方法
 18      */
 19     public void fun(){
 20         System.out.println("存在有方法体的方法!");
 21     }
 22     
 23     /**
 24      * 抽象方法
 25      */
 26     public abstract void print();
 27     
 28 }
 29 
 30 /**
 31  * 子类:一个子类只能继承一个抽象类,属于单继承局限
 32  */
 33 class F extends B{
 34     @Override
 35     public void print() {//强制重写的抽象父类的抽象方法
 36         System.out.println("Hello");
 37     }
 38 }
 39 
 40 class Test{
 41     public static void main(String[] args) {
 42         B b= new F();//向上转型
 43         b.fun();
 44         b.print();//重写的print()方法
 45     }
 46 }
 47 
 48 注意:
 49     1.抽象类可以存在属性,那么抽象类就一定会存在构造方法,目的:为属性初始化,并且子类对象实例化
 50       的时候依然先执行父类构造,再调用子类构造
 51     2.抽象类不能用final定义:抽象类必须有子类,而final定义的类不能有子类
 52     3.外部抽象类不允许用static,内部的抽象类可以使用static,(此时的内部抽象类 = 外部抽象类)
 53       继承时使用“外部类.内部类”的形式表示类名称
 54 范例:
 55 /**
 56  * 父类
 57  */
 58 public abstract class C {
 59     //static 定义的内部类属于外部类
 60     static abstract class G{
 61         public abstract void print();
 62     }
 63 }
 64 
 65 /**
 66  * 子类
 67  */
 68 class X extends C.G{    //调用G的抽象方法
 69     @Override
 70     public void print() {
 71         System.out.println("*************");
 72     }
 73 }
 74 
 75 
 76 class TestC{
 77     public static void main(String[] args) {
 78         C.G cg= new X(); //调用G的抽象方法
 79         cg.print();
 80     }
 81 }
 82 
 83 任何情况下,如果要执行类中的static方法【抽象类】的时候,都可以在没有对象的时候直接调用
 84 范例:
 85 public abstract class StaticDemo {
 86     
 87     //静态普通方法
 88     public static void print(){
 89         System.out.println("Hello");
 90     }
 91 }
 92 
 93 class TestSttic{
 94     public static void main(String[] args) {
 95         //不要实例化对象,直接【类.方法】
 96         StaticDemo.print();
 97     }
 98 }
 99 
100 
101 ★继承:唯一的对象,单例★
102 有时,抽象类只需一个特定的系统子类操作,可以忽略外部子类(父类内的带static的子类)
103     为用户隐藏不需要知道的子类
104 范例:
105 public abstract class InsideSonType {
106     public abstract void print();
107     
108     private static class B extends InsideSonType{  //内部抽象类子类
109         public void print(){    //覆写抽象类的方法
110             System.out.println("Hello World!");
111         }
112     }
113     
114     //这个方法不受实例化对象的控制
115     public static InsideSonType getInstance(){
116         return new B();
117     }
118     
119 public class Test {
120 
121     public static void main(String[] args) {    
122         //此时取得抽象类对象的时候,完全可以不需知道子类B的存在
123         InsideSonType insideSonType = InsideSonType.getInstance(); 
124         insideSonType.print();
125     }
126 }
127 
128 类实例创建过程:
129     按照父子继承关系进行初始化,首先执行父类的初始化块,然后执行父类的构造方法,
130     其次执行继承的子类的初始化块,最后执行子类的构造方法
131 类实例销毁:
132     先销毁子类部分,再销毁父类部分
133 范例:
134 public abstract class AbstractNum {
135     /**
136      * 父类的构造方法
137      */
138     public AbstractNum(){
139         this.print();//调用print()方法
140     }
141     
142     /**
143      * 抽象方法
144      */
145     abstract void print();
146     
147     /**
148      * 子类
149      */
150     class B extends AbstractNum{
151         private int num = 100;
152         ★没声明调用父类的构造方法,子类默认执行的是父类的无参构造方法★
153         public B(int num){    //子类带参构造方法
154             this.num = num;
155         }
156         @Override
157         void print() {
158             System.out.println("num = " + num);
159         }
160     }
161 }
162 
163 public class Test {
164 
165     public static void main(String[] args) {
166         new B(30);//只执行到父类的构造方法
167     }
168 }
169 
170 
171 ◆◆◆◆◆◆◆◆◆模板设计模式◆◆◆◆◆◆◆◆◆(工具画类图:umll)
172 ☉机器人:充电、工作;
173 ☉人:吃饭、工作、睡觉;
174 ☉猪: 吃饭、睡觉。 
175 ☉要求可以实现以上的操作控制,即:可以任意的控制人、机器人、猪的操作行为(吃、睡、工作)
176 abstract class Action {
177     public static final int EAT = 1;    //常量,奇数比较合适
178     public static final int SLEEP = 5;
179     public static final int WORK = 7;
180     public void command(int flag){
181         //switch 只支持数值判断,而if支持条件判断
182         switch(flag){
183         case EAT:
184             this.eat();
185             break;
186         case SLEEP:
187             this.sleep();
188             break;
189         case WORK:
190             this.work();
191             break;
192         case EAT+WORK:
193             this.eat();
194             this.work();
195             break;
196         }
197     }
198     //因为现在不确定子类的实现是什么样的
199     public abstract void eat();
200     public abstract void sleep();
201     public abstract void work();
202 }
203 
204 //子类Robot
205 public class Robot extends Action {
206     public void eat(){
207         System.out.println("机器人补充能量!");
208     }
209     public void sleep(){}
210     public void work(){
211         System.out.println("机器人正在努力工作!");
212     }
213 }
214 
215 //子类Human
216 public class Human extends Action {
217      public void eat(){
218          System.out.println("人类正在吃饭!");
219      }
220      public void sleep(){
221         System.out.println("人类正在睡觉休息!"); 
222      }
223      public void work(){
224          System.out.println("人为了梦想在努力工作!");
225      }
226 }
227 
228 //子类Pig
229 public class Pig extends Action{
230      public void eat(){
231          System.out.println("猪正在啃食槽!");
232      }
233      public void sleep(){
234         System.out.println("猪在睡觉养膘!"); 
235      }
236      public void work(){}
237 }
238 
239 //测试类
240 public class TestDemo {
241     public static void main(String args[]){
242         fun(new Robot());//调用static方法,不需实例化对象,直接调方法
243         fun(new Human());
244         fun(new Pig());
245     }
246     public static void fun(Action act){
247         act.command(Action.EAT);
248         act.command(Action.SLEEP);
249         act.command(Action.WORK);
250     }
251 }

 

posted @ 2016-03-18 05:21  Ivy_Xu  阅读(276)  评论(0编辑  收藏  举报