代码之家  ›  专栏  ›  技术社区  ›  woockashek

Java中同一类的继承和组合

  •  0
  • woockashek  · 技术社区  · 6 年前

    我在github上发现了以下代码:

    public class DummySSLSocketFactory extends SSLSocketFactory {
    
        private static final Logger LOG = LoggerFactory.getLogger(DummySSLSocketFactory.class);
        private SSLSocketFactory factory;
    
        public DummySSLSocketFactory() {
            try {
                SSLContext sslContext = SSLContext.getInstance("TLS");
                TrustManager[] trustManagers = new TrustManager[] {new DummyTrustManager()};
                sslContext.init(null, trustManagers, new java.security.SecureRandom());
                factory = sslContext.getSocketFactory();
            } catch (Exception e) {
                throw new RuntimeCamelException("Error creating DummySSLSocketFactory: " + e.getMessage(), e);
            }
        }
    
        /**
         * Must provide this getDefault operation for JavaMail to be able to use this factory.
         */
        public static SocketFactory getDefault() {
            LOG.warn("Camel is using DummySSLSocketFactory as SSLSocketFactory (only to be used for testing purpose)");
            return new DummySSLSocketFactory();
        }
    
        public String[] getDefaultCipherSuites() {
            return factory.getDefaultCipherSuites();
        }
    
        public String[] getSupportedCipherSuites() {
            return factory.getSupportedCipherSuites();
        }
    
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
            return factory.createSocket(socket, host, port, autoClose);
        }
    
        public Socket createSocket(String host, int port) throws IOException {
            return factory.createSocket(host, port);
        }
    
        public Socket createSocket(String host, int port, InetAddress localAddress, int localPort)
            throws IOException {
            return factory.createSocket(host, port, localAddress, localPort);
        }
    
        public Socket createSocket(InetAddress host, int port) throws IOException {
            return factory.createSocket(host, port);
        }
    
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
            throws IOException {
            return factory.createSocket(address, port, localAddress, localPort);
        }
    
        public Socket createSocket() throws IOException {
            // must have this createSocket method
            return factory.createSocket();
        }
    
    }
    

    类似的实现在不同的项目中广泛使用。 我试图弄清楚同时使用继承和组合的目的是什么。看起来只要有一个返回结果的工厂方法就足够了 sslContext.getSocketFactory(); 因为它根本没有扩展类。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Jul10    6 年前

    我不知道谁编写了这段代码的确切意图是什么,但在这种类的组织中,很明显,使用组合和继承, DummySSLSocketFactory公司 可以 使用受保护的方法 实施于 SSLSocketFactory公司 甚至是上面的类(使用super)。
    这是可能的,因为 DummySSLSocketFactory 具有对其父类的引用 SSLSocketFactory

     private SSLSocketFactory factory;
    

    在DummySSLSocketFactory的构造函数中设置

    factory = sslContext.getSocketFactory();
    

    如果没有这个参考,您将能够使用super访问SSLSocketLayer,但不能使用更高级别的类。

        2
  •  0
  •   DwB    6 年前

    这是一种常见的模式(如您所述)。

    子类可以扩展类(或实现接口)以建立“is-A”关系。 在你的例子中, DummySSLSocketFactory is-a SSLSocketFactory . “is-a”关系允许多态性。

    子类可能不希望完全重写(或在接口的情况下实现)方法, 因此,它使用组合来获得一些已经覆盖了无趣但必需的方法的内容。 为此, 子类将向组合成员转发对“无趣”(我在那里的术语)方法的调用。 在您的示例中,原始类 SSLSocketFactory公司 提供用户不感兴趣的东西的“默认”实现 DummySSLSocketFactory公司

    向组合成员转发调用是代理模式的一种变体。它不是完全代理,因为它改变了功能。