java学习笔记四

来源:互联网 发布:柳长街知乎 编辑:程序博客网 时间:2024/05/16 01:50
关于Lazy initialization:来自wiki
In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.
This is typically accomplished by maintaining a flag indicating whether the process has taken place. Each time the desired object is summoned, the flag is tested. If it is ready, it is returned. If not, it is initialized on the spot.
See lazy evaluation for a general treatment of this idea. In heavily imperative languages this pattern carries hidden dangers, as does any programming habit that relies on shared state.
Java
Here is an example in Java.
public class Fruit {
 
    private static final Map<String,Fruit> types = new HashMap<String, Fruit>();
    private final String type;
 
    // using a private constructor to force use of the factory method.
    private Fruit(String type) {
        this.type = type;
    }
 
    /**
    * Lazy Factory method, gets the Fruit instance associated with a
    * certain type. Instantiates new ones as needed.
    * @param type Any string that describes a fruit type, e.g. "apple"
    * @return The Fruit instance associated with that type.
    */
    public static synchronized Fruit getFruit(String type) {
        if (!types.containsKey(type)) {
            types.put(type, new Fruit(type)); // Lazy initialization
        }
        return types.get(type);
    }
}
2 关于构造函数继承初始化:如果父类和子类都是没有带参数的默认构造函数,子类在创建对象的时候会自动调用父类的构造函数,并且不需要supper进行显示调用;
如果父类的构造函数带有参数且仅仅有改构造函数,子类的构造函数也带有参数,那么子类需要显示的调用父类中带有参数的构造函数
如果父类的构造函数有覆盖,即由几个不同的构造函数,子类需要显示的指明调用哪一个构造函数,否则会调用默认不带参数的构造函数。
举个简单例子:
package access;
public class parent {
public parent()
{
System.out.println("it is a parenet contactor");
}
public parent(int i )
{
System.out.println("it is a parenet contactor "+i);
}
}
 
package access;
public class Child extends parent{
public Child()
{
System.out.println("it is a child contactor");
}
public Child(int i)
{
//super(i);
System.out.println("it is a child contactor "+i);
}
public static void main(String args[])
{
Child a =new Child(1);
Child b = new Child();
}
}
输出结果为:it is a parenet contactor
it is a child contactor 1
it is a parenet contactor
it is a child contactor
如果将//super(i);的注释去掉。结果将变为以下:it is a parenet contactor 1
it is a child contactor 1
it is a parenet contactor
it is a child contactor
 
Java Delegation:
关于delegation,翻译即为委派,委托,具体什么意思呢,就是通常有一个类是实实在在干活的,但是往往还存在一个委托类,实实在在干活的类是委托类中的一个成员变量,他需要具体干的活在委托类里面去实现。
有点类似这种情况,假如你的客户出了一个问题,你去客户现场帮忙解决问题,你发现了问题但是你实际不知道如何去做,你可能需要公司里面一些技术人员的支持,这些技术人员给你实实在在解决问题,但是对于客户,他看到的是你帮他们解决了问题,你就是这个委托的类。哈哈,不知道这么理解对否?
这样做有什么好处,我的理解是出来问题你去负责沟通和接口,而真正的干活的人却可以自由变化,可以更好的去变更,更灵活。
 
说白了委托就是组合加个forwarding方法,即将一个类的对象作为另一个类的成员变量,将原来那个类的方法加以wrapper再调用。
下面的内容来自wiki:
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object. It passes the buck, so to speak (technically, an Inversion of Responsibility). The helper object is called the delegate. The delegation pattern is one of the fundamental abstraction patterns that underlie other software patterns such as composition (also referred to as aggregation), mixins and aspects.
Java examplesSimpleIn this Java example, the Printer class has a print method. This print method, rather than performing the print itself, delegates to class RealPrinter. To the outside world it appears that the Printer class is doing the print, but RealPrinter class is the one actually doing the work.
Delegation is simply passing a duty off to someone/something else. Here is a simple example:
 class RealPrinter { // the "delegate"     void print() {        System.out.print("something");      } }  class Printer { // the "delegator"     RealPrinter p = new RealPrinter(); // create the delegate      void print() {        p.print(); // delegation     }  }  public class Main {     // to the outside world it looks like Printer actually prints.     public static void main(String[] args) {         Printer printer = new Printer();         printer.print();     } }
ComplexBy using interfaces, delegation can be made more flexible and typesafe. "Flexibility" here means that C need not refer to A or B in any way, as the switching of delegation is abstracted from C. Needless to say, toA and toB don't count as references to A and B. In this example, class C can delegate to either class A or class B. Class C has methods to switch between classes A and B. Including the implements clauses improves type safety, because each class must implement the methods in the interface. The main tradeoff is more code.
interface I {    void f();    void g();} class A implements I {    public void f() { System.out.println("A: doing f()"); }    public void g() { System.out.println("A: doing g()"); }} class B implements I {    public void f() { System.out.println("B: doing f()"); }    public void g() { System.out.println("B: doing g()"); }} class C implements I {    // delegation    I i = new A();     public void f() { i.f(); }    public void g() { i.g(); }     // normal attributes    public void toA() { i = new A(); }    public void toB() { i = new B(); }} public class Main {    public static void main(String[] args) {        C c = new C();        c.f();     // output: A: doing f()        c.g();     // output: A: doing g()        c.toB();        c.f();     // output: B: doing f()        c.g();     // output: B: doing g()    }}
 
Java继承还是组合:
Both composition and inheritance allow you to place subobjects inside your new class (composition explicitly does this—with inheritance it’s implicit). You might wonder about the difference between the two, and when to choose one over the other. 
Composition is generally used when you want the features of an existing class inside your new class, but not its interface. That is, you embed an object so that you can use it to implement features in your new class, but the user of your new class sees the interface you’ve defined for the new class rather than the interface from the embedded object. For this effect, you embed private objects of existing classes inside your new class. 
 
When you inherit, you take an existing class and make a special version of it. In general, this means that you’re taking a general-purpose class and specializing it for a particular need. With a little thought, you’ll see that it would make no sense to compose a car using a vehicle object—a car doesn’t contain a vehicle, it is a vehicle. The is-a relationship is expressed with inheritance, and the has-a relationship is expressed with composition. 
关于什么时候用继承,什么时候用组合?下面的话可以给一些参考:
One of the clearest ways to determine whether you should use composition or inheritance is to ask whether you’ll ever need to upcast from your new class to the base class. If you must upcast, then inheritance is necessary, but if you don’t need to upcast, then you should look closely at whether you need inheritance. 
 
Protected在继承中的作用就像是你们家族的秘密或者经验,外人不知道,你们这些有祖孙关系的人都知道的。
关于upcasting:
 
Casting from a derived type to a base type moves up on the inheritance diagram, so it’s commonly referred to as upcasting. Upcasting is always safe because you’re going from a more specific type to a more general type. That is, the derived class is a superset of the base class. It might contain more methods than the base class, but it must contain at least the methods in the base class. The only thing that can occur to the class interface during the upcast is that it can lose methods, not gain them. This is why the compiler allows upcasting without any explicit casts or other special notation. 
 
 
原创粉丝点击