抽象类
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 }