上二篇主要讲了面向对象理论中抽象类的具体应用。但是举的例子很简单。所以这一篇想模拟一个实际的项目来具体说明一下抽象类的具体应用。采用的语言是Java必定会这种语言的童鞋很多。
模拟开发一个播放视频的万能播放器的功能。可以播放AVI、MPEG、RMVB 对这三种格式的视频播放。
例如:001.avi 自动选择播放AVI格式的功能 001.mpeg 自动选择播放MPEG格式的功能 001.rmvb 自动选择播放RMVB格式的功能
其它格式,提示用户。此文件格式不能进行播放。具体播放功能可以不用实现。可以用信息来代替。
通过上面的内容我们知道面向对象的主体是播放器(面向对象开发主要就是在需求中找到相应的对象)方法体是播放视频功能,实现的功能是(播放xxxxxx格式视频)具体功能不用实现。只是模拟一下播放的过程。
通过上面分析 抽象类 :播放器 抽象方法 :播放功能
子类 Avi、Mpeg、RMVB
思路清晰了,下面开始编写代码。
下面是代码实现,已经测试过:
定义抽象类PlayerHelper:
1 package com.PlayerHelper; 2 3 public abstract class PlayerHelper { 4 public String FileName = ""; 5 6 public PlayerHelper(String FileName) { 7 this.FileName = FileName; 8 } 9 10 public abstract void Play() throws Exception; 11 }
题外话:
这样写异常还有一个好处就是。想调用此方法时强制你写异常处理。防止你发生漏写的情况。
定义子类Avi:
1 package com.PlayerHelper; 2 3 public class Avi extends PlayerHelper { 4 5 public Avi(String FileName) { 6 super(FileName); 7 // TODO Auto-generated constructor stub 8 } 9 10 @Override 11 public void Play() throws Exception { 12 try { 13 System.out.print("播放AVI格式视频"); 14 } catch (Exception ex) { 15 throw new Exception(ex); 16 } 17 } 18 }
定义子类Mpeg:
1 package com.PlayerHelper; 2 3 public class Mpeg extends PlayerHelper { 4 5 public Mpeg(String FileName) { 6 super(FileName); 7 } 8 9 @Override 10 public void Play() throws Exception { 11 System.out.print("播放Mpeg格式视频"); 12 } 13 }
定义子类Rmvb:
1 package com.PlayerHelper; 2 3 public class Rmvb extends PlayerHelper { 4 5 public Rmvb(String FileName) { 6 super(FileName); 7 } 8 9 @Override 10 public void Play() throws Exception { 11 System.out.print("播放RMVB格式视频"); 12 } 13 }
测试类 Test
1 package com.PlayerHelper; 2 3 public class Test { 4 public static void main(String[] args) { 5 PlayerHelper playhelper = new Avi("001.avi"); 6 try { 7 playhelper.Play(); 8 } catch (Exception ex) { 9 System.out.print(ex.toString()); 10 } 11 } 12 }
上面的代码这么写没有问题,但是你会发现越写main中的代码越多。而且达不到万能播放的效果。如果现在播放 001.mpeg 怎么办
PlayerHelper playhelper=new Avi("001.mpeg");
你肯定会说我加一个方法。获取文件扩展名的功能。然后根据扩展名在去调用各个子类。这样的结果是代码越来越多。以后维护起来越来越乱。那怎么办。很简单我们在建立一个管理类,让其去做自动识别播放的功能
管理类新鲜出炉
1 package com.PlayerHelper; 2 3 public class PlayerManagement { 4 public PlayerHelper playerhelper; 5 6 public boolean Player(String FileName) throws Exception { 7 String FileExtension = ""; 8 FileExtension = FileName.substring(FileName.lastIndexOf(".") + 1); 9 10 if (FileExtension != "" || null != FileExtension) { 11 switch (FileExtension.toUpperCase()) { 12 case "AVI": 13 playerhelper = new Avi(FileName); 14 break; 15 case "MPEG": 16 playerhelper = new Mpeg(FileName); 17 break; 18 case "RMVB": 19 playerhelper = new Rmvb(FileName); 20 break; 21 default: 22 return false; 23 } 24 try { 25 playerhelper.Play(); 26 } catch (Exception ex) { 27 throw new Exception(ex); 28 } 29 return true; 30 } else { 31 return false; 32 } 33 } 34 }
测试类代码更改为
1 package com.PlayerHelper; 2 3 public class Test { 4 public static void main(String[] args) { 5 boolean bolTemp = false; 6 PlayerManagement pm = new PlayerManagement(); 7 try { 8 bolTemp = pm.Player("001.avi"); 9 if (bolTemp == false) { 10 System.out.print("此文件格式不能进行播放"); 11 } 12 } catch (Exception ex) { 13 System.out.print(ex.toString()); 14 } 15 } 16 }
public boolean Player(String FileName) throws Exception
方法的返回值为什么要采用布尔型。是因为 播放成功与否就二个状态
你让你朋友帮你抢小米手机,抢到以后再给他钱。结果出现下面二种情况你会选择那种情况。
我想大家肯定会选择第一种。我们做程序一定要站在用户的角度考虑问题。所以要加一个播放成功与否的状态。
FileName.substring(FileName.lastIndexOf(".") + 1);
获取文件名扩展名的方法。这个随便。我只是随便写了一个,你可能有更好的实现办法。总之实现了就可以。
正常这块也应该加一个单独的异常。获取文件名扩展名是最容易出错的地方。因为不可能每一个文件名称都像 001.avi 那个标准
是不是感觉抽象类很有用,假如以后追加 其它格式 只需增加相应的子类功能。