试了试简单工厂模式代码,懂了这个设计模式,却产生了新的疑惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
amiwrong123
V2EX    程序员

试了试简单工厂模式代码,懂了这个设计模式,却产生了新的疑惑

  •  a href="Javascript:" Onclick="downVoteTopic(592767);" class="vote">
  •   amiwrong123 2019-08-17 21:33:35 +08:00 3644 次点击
    这是一个创建于 2254 天前的主题,其中的信息可能已经有所发展或是发生改变。

    参考了博客 https://www.jianshu.com/p/e55fbddc071c 考虑此设计模式中有产品类,工厂类和测试类。 首先产品类在 other 包中:

    package other; public abstract class Product{ public abstract void Show(); } //具体产品类 A class ProductA extends Product{ @Override public void Show() { System.out.println("生产出了产品 A"); } } //具体产品类 B class ProductB extends Product{ @Override public void Show() { System.out.println("生产出了产品 C"); } } //具体产品类 C class ProductC extends Product{ @Override public void Show() { System.out.println("生产出了产品 C"); } } 

    工厂类在 other 包中:

    package other; public class Factory { public static Product Manufacture(String ProductName){ //工厂类里用 switch 语句控制生产哪种商品; //使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。 switch (ProductName){ case "A": return new ProductA(); case "B": return new ProductB(); case "C": return new ProductC(); default: return null; } } } 

    最后是测试类,在默认包中:

    //工厂产品生产流程 import other.Factory; public class SimpleFactoryPattern { public static void main(String[] args){ Factory mFactory = new Factory(); //客户要产品 A try { //调用工厂类的静态方法 & 传入不同参数从而创建产品实例 mFactory.Manufacture("A").Show(); }catch (NullPointerException e){ System.out.println("没有这一类产品"); } //客户要产品 B try { mFactory.Manufacture("B").Show(); }catch (NullPointerException e){ System.out.println("没有这一类产品"); } //客户要产品 C try { mFactory.Manufacture("C").Show(); }catch (NullPointerException e){ System.out.println("没有这一类产品"); } //客户要产品 D try { mFactory.Manufacture("D").Show(); }catch (NullPointerException e){ System.out.println("没有这一类产品"); } } } 

    疑问 1.Product 文件中,如果 Product 抽象类没有加 public,那么测试类的每个Show()处都会报错 cant access show() in other.Product.然后这里我加上了 public 就不会报这个错了。但为什么测试类不需要加上import other.Product呢,即使我加上,idea 也告诉我说,导入的这个Product从来没被用过?

    疑问 2.现在的代码能运行,但每个Show()处都会报警告,说调用 show 可能引发空指针异常。我以为把工厂类的 default 行为改了改成return new ProductC();就不会报这个警告了。但还是报这个警告,为啥啊?

    第 1 条附言    2019-08-17 23:15:53 +08:00
    疑问 2 解决了,好像真是 idea 反应慢,default 行为改了就好了,不会报警告了。
    12 条回复    2019-08-17 23:30:21 +08:00
    v2overflow
        1
    v2overflow  
       2019-08-17 22:06:50 +08:00
    2,没 break 吧
    amiwrong123
        2
    amiwrong123  
    OP
       2019-08-17 22:14:59 +08:00
    @v2overflow
    你说 switch case 啊,因为每个分支都有 return,所以不用加 break,加在后面也执行不到。
    ywcjxf1515
        3
    ywcjxf1515  
       2019-08-17 22:18:10 +08:00 via iPad
    mFactory.Manufacture("XXX")的结果是,父类引用指向子类对象,后面 show 调用的是父类的方法,方法内容由子类定,父类的 show 方法是默认的包可见性,就不能 access 父亲的 show 方法。你可以向下转型,子类引用指向子类对象,这样 show 方法是子类的 show 方法,可见性是 public。
    iEverX
        4
    iEverX  
       2019-08-17 22:20:00 +08:00
    1. 因为确实没用到。Java 从来不要求使用了方法就需要 import
    2. 应该没问题,ide 反应慢吧
    amiwrong123
        5
    amiwrong123  
    OP
       2019-08-17 22:31:42 +08:00
    @ywcjxf1515
    等一下,父类的 show 方法是 public 的啊,不是默认包可见啊。我比较纳闷的是,为毛不加上 import other.Product,它还能调用 show 呢。。
    而且我发现报错信息 cant access show() in other.Product 这句里面,为毛报错信息都知道 Product 都知道这个 Product 在 other 包而不是其他包中呢。。。
    amiwrong123
        6
    amiwrong123  
    OP
       2019-08-17 22:34:11 +08:00
    @iEverX
    1.你说的这点,勉强我可以接受,但我还没在书中找到证实。。
    2.应该不是 idea 反应慢吧,不然它这反射弧也太长了吧。。。
    ywcjxf1515
        8
    ywcjxf1515  
       2019-08-17 22:55:23 +08:00 via iPad
    @amiwrong123 疑问 1 里你补加的 public 是在类上的吧,没加之前是默认的包可见性,方法也跟着是。
    因为你调用这个 show 方法时,没有出现父类,就不用导入。你可以写一个工厂类,工类类方法返回一个 ArrayList,调用这个工厂类方法,同样不用引用变量接着,直接调用 ArrayList 的方法,你会发现同样不用导入 ArrayList。
    amiwrong123
        9
    amiwrong123  
    OP
       2019-08-17 22:58:58 +08:00
    @iEverX
    看到了这句 You may live without any import statement when you always specify the full qualified name of classes。
    现在我的理解是:编译器知道 mFactory.Manufacture("XXX")的返回值类型是 other.Product,而且编译器不仅知道返回值类型,而且它还不用我告诉它这个类型(指在测试类中加入 import other.Product ),就算我加了 import other.Product,它也会对我说:“我不用你的,我自己知道!”(报警告,此 other.Product 从未被用过)
    amiwrong123
        10
    amiwrong123  
    OP
       2019-08-17 23:12:04 +08:00
    @ywcjxf1515
    关于访问权限我懂了,先是看类的访问权限,再是看类里各个方法的访问权限。两个都可以才可以访问到。
    关于直接调用 show,直接原因应该就是因为我没有用引用去接产品类对象,所以可以直接调用。但总感觉没理解到位==
    amiwrong123
        11
    amiwrong123  
    OP
       2019-08-17 23:16:59 +08:00
    @iEverX
    疑问 2 解决,就是因为 default 返回 null 的原因。真的反应慢。
    iEverX
        12
    iEverX  
       2019-08-17 23:30:21 +08:00
    import other.Product 只是把名字 Product 当作 other.Product。既然没有用 Product 这个名字,当然就不用 import
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2485 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 04:56 PVG 12:56 LAX 21:56 JFK 00:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86