The three major characteristics of java object-oriented (encapsulation, inheritance, polymorphism)

1. Packaging

       Encapsulation refers to hiding the state information of the object inside the object, and does not allow external programs to directly access the internal information of the object, but operates and accesses the internal information through the external methods provided by the class.

Encapsulation can achieve the following purposes:

1) Hide the implementation details of the class

2) Allow users to access data only through predetermined methods, so that control logic can be added to this method to limit unreasonable access to member variables

3) Data inspection can be carried out, which is conducive to ensuring the integrity of data information

4) It is easy to modify and improve the maintainability of the code.

In order to achieve good encapsulation, two aspects need to be considered:

1) Hide the member variables and implementation details of the object, and do not allow direct external access

2) Expose the method and let the method control the safe access and operation of these member variables

Use access control modifiers

        Java provides three access control characters: private, protected, public, which represent three access control levels respectively. There is also an access control level without any access control characters.

       private (current class access rights) → default (package access rights) → protected (package access, subclass access rights) → public (public access rights)

 

Basic principles of access modifier usage:

1) Most member variables are modified with private, and only some static modified member variables like global variables may consider public modification. In addition, some methods are only used to help implement other methods of the class, these methods become tool methods, and the tool methods should also be decorated with private.

2) If a class is mainly used as the parent of other classes, and most of the methods in this class may only be overridden by its subclasses, but not directly called by the outside world, you should use

protected decorates these methods.

3) Methods that you want to expose to other classes should use public modification. Therefore, the constructor of a class is decorated with public, allowing instances of the class to be created elsewhere. Because external classes usually want to be freely called by other classes, most external classes are decorated with public.

 

deep into the constructor

    1) When the programmer calls the constructor, the system allocates memory space for the object, and the object has already been created, but the object cannot be accessed by external programs, and can only be referenced by this in the constructor

    2) If constructor B completely contains the code of constructor A, if the constructor is called through the new keyword, it will cause the program to recreate an object, but you can use this to call the corresponding constructor. The example is as follows:

 

public class Apple{

public String name;
public String color;
public double weight;

public Apple(){}

public Apple(String name,String color){
this.name=name;
this.color=color;

}

public Apple(String name,String color, double weight){
   this (name,color);   // Call the initialization code of another overloaded constructor through this 
  this .weight= weight;

}


}

 

 

 

2. Class inheritance

       Java implements class inheritance through the extends keyword. The class that implements inheritance is called a subclass, and the class that is inherited is called a parent class. Some also call it super class, base class. The relationship between parent class and child class is a general and special relationship.

        Because the subclass is a special parent class, the scope of the parent class is larger than that of the subclass. For example, the scope of the fruit class is larger than that of the apple, so it can be considered that the parent class is a large class and the subclass is a small class.

        It's worth pointing out that Java subclasses cannot get the superclass's constructor.

      The following is an example of a subclass inheriting a parent class:

public class Fruit(){

public double weight;

public void info(){System.out 
.println ( " I am a fruit, heavy " +weight+ " g " );
}

}

     Next, define a subclass of the Fruit class, the code is as follows:

public class Apple extends Fruit(){

public static void main(String[] args){
Apple a=new Apple();
a.weight=56;
a.info();

}


}

       In the above program, Apple is basically an empty class, which only contains a main method. After the Apple object is created, you can access the weight instance variable and info instance method of the object. This is the role of inheritance, which can be understood as inheriting the parent class. heritage.

A Java class can only have one direct parent class, but can have multiple or even unlimited indirect parent classes. Oblect is the parent class of all classes, either an indirect parent class or a direct parent class

 

Override (Override) the method of the parent class

        The subclass extends the parent class, and the subclass is a special parent class. Most of the time, the subclass is always based on the parent class, with additional member variables and methods. But there is an exception. The subclass overrides the method of the parent class according to its own needs. Overriding is also called overriding. The two are the same concept.

       The rewriting of the method follows the principle of " two same, two small, one big ". Two same methods refer to the same method name and the same formal parameter list; two little fingers' return value type of subclass method is smaller or equal to that of parent class method. The exception class declared by the subclass method should be smaller or equal to the exception thrown by the superclass method declaration; one is that the access rights of the subclass method should be greater or equal than the access rights of the superclass.

   Some notes:

1) Overriding methods are either class methods or instance methods.

2) After the subclass overrides the parent class method, the subclass object cannot access the overridden method in the parent class. When it can be called in the subclass method, you can use super (the parent class

       instance) keyword or parent class name or object reference name as the caller to call the overridden method

3) If the parent class method has the private modification, the child class cannot access and override the method. If the subclass also defines a method that follows the "two same, two small, one big" rule, it is still not overriding, it can only be said that a new method is defined.

super limited

     If you need to call the overridden instance method of the parent class in the subclass, you can use the super limit to call the overridden method of the parent class.

     super is a keyword provided by Java to qualify the object to call instance variables or methods it inherits from the parent class. Just as this cannot appear in statically modified methods, super cannot appear in statically modified methods.

     If super is used in a constructor, super is used to limit the initialization of the constructor to the instance variables inherited by the object from the parent class, rather than the instance variables defined by the class itself.

    If the subclass defines an instance variable with the same name as the parent class, the instance variable of the subclass will hide the instance variable of the parent class. In this case, the subclass directly accesses the instance variable to the subclass instance variable and cannot access the parent class by default. Hidden instance variables. At this time, the super keyword can be used in the instance method of the subclass to access the hidden instance variables of the superclass.

super calls the constructor of the parent class

    The subclass does not get the constructor of the superclass, but the subclass constructor can call the initialization code of the superclass constructor, which is similar to the previous one calling another overloaded constructor. Using super to call the parent class constructor must appear in the first line of the child class constructor execution body, so the this call and the super call will not appear at the same time.

   The subclass calls the superclass constructor in the following situations:

    1) The execution body of the subclass constructor uses super to display the call to the parent class constructor in the first line, and the system will call the constructor corresponding to the parent class according to the actual parameters passed in the super call

    2) The first line of code of the subclass constructor execution body uses this to display the call to the overloaded constructor in this class, and the system will call this class according to the actual parameter list passed in the this call

          Another corresponding constructor, executing another constructor of this class will call the parent class constructor

    3) There is neither super call nor this call in the execution body of the subclass constructor. The system will implicitly call the no-argument constructor of the parent class before executing the subclass constructor.

 

3. Polymorphism

       Java reference variables have two types: a compile-time type and a runtime type. The compile-time type is determined by the type with which the variable was declared. The use-time type is determined by the object actually assigned to the variable. If the compile-time type and the run-time type are inconsistent, so-called polymorphism may occur.

       Take a look at the following procedure:

class BaseClass 
{
    public int book = 6;
    public void base(){
    System.out.println("父类的普通方法");
    }
    public void test(){
    System.out.println("父类被覆盖的方法");
    }

    }

class SubClass extends BaseClass
{
    public String book = "轻量级JavaEE企业应用实战";
    public void test(){
     System.out.println("子类覆盖父类的方法");
    }

    public void sub(){
    System.out.println("子类的普通方法");
    }

     
    public static void main(String[] args) 
    {
        BaseClass bc = new BaseClass();
        System.out.println(bc.book);
        bc.base();
        bc.test();

        System.out.println();
        SubClass sc = new SubClass();
        System.out.println(sc.book);
        sc.sub();
        sc.test();

        System.out.println();
        BaseClass ploymophicBc = new SubClass();    //编译时类型与运行时类型不一致
        System.out.println(ploymophicBc.book);
        ploymophicBc.base();
        ploymophicBc.test();
// ploymophicBc.sub(); 编译会出错,无法调用 } }

输出:

---------- 运行java程序 ----------
6
父类的普通方法
父类被覆盖的方法

轻量级JavaEE企业应用实战
子类的普通方法
子类覆盖父类的方法

6
父类的普通方法
子类覆盖父类的方法

输出完成 (耗时 0 秒) - 正常终止

 

        从上面可以看出,编译时类型与引用类型不一致时,调用的是子类覆盖后的方法。

       因为子类其实是一种特殊的父类,因此Java允许把一个子类对象直接付给一个父类引用变量,无需任何类型转换,或者成为向上转型,由系统自动完成。

        当把子类对象直接赋给父类引用变量时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征,这可能出现:相同的变量,调用同一个方法时呈现出不同的行为特征

引用变量的强制类型转换

        编写Java程序时,引用变量只能调用编译时类型的方法,而不能调用运行时类型的方法,但它实际所引用的对象确实包含该方法。如果需要让这个引用变量调用它运行时类型的方法,则必须把他强制类型转换成运行时类型,强制类型转换格式是(type)valiable。

      强制类型转换不是万能的,需要注意:

      1)基本类型之间的转换只能在数值类型之间进行,包括整型,字符型,浮点型。不能与布尔型类型进行转换

      2)引用类型之间的转换只能在具有继承关系的两个类型之间进行。如果没有继承关系,强制类型转换会编译出错

       在进行强制类型转换之前,先用instanceof运算符判断是否可以成功转换,从而避免ClassCastException异常,这样可以使程序更加健壮。,用法如下:

if(objpri instanceof String){
String str = (String)objPri;
}

 

四.继承与组合

        继承和组合都是实现类复用的重要手段,但继承的一大坏处是破坏程序的封装性,采用组合来实现类复用有更好的封装性能。

     为了保证父类有良好的封装性,不会被子类随意改变,设计父类通常遵循以下规则:

      1)尽量隐藏父类的内部数据。尽量把父类的所有成员变量都设计成private访问类型,不要让子类直接访问父类的成

            员变量。

      2)不要让子类可以随意访问,修改父类的方法。父类中那些仅为辅助其他的工具方法,应该使用private访问修饰符

            控制修饰,让子类无法访问该方法;如果父类中的方法需要被外部调用,则必须以public修饰,但又不希望被子类

            重写该方法,可以使用final修饰符来修饰该方法;如果希望父类的某个方法被子类重写,但不希望被其他类自由

            访问,则可以使用protected来修饰该方法。

        3)尽量不要在父类构造器中调用要被子类重写的方法。

       如下程序:

class Base 
{
    public Base(){
        test();
    }
    public void test(){
    System.out.println("被子类重写的方法");
    }
}
     class Sub extends Base
    {
      private String name;
      public void test(){
      System.out.println("子类重写父类的方法,其name字符串长度"+name.length());
      }
     
     public static void main(String[] args) 
    {
            //这一行引发空指针异常
        Sub s = new Sub();
    }
    
    
}

        如果想把某些类设置成最终类,既不能当成父类,则可以使用final修饰这个类。除此之外,使用private修饰这个类的所有构造器,从而保证子类无法调用该类的构造器。也就无法继承该类。对于把所有的构造器都使用private修饰的父类,可另外提供一个静态方法,用于创建该类的实例。

到底何时需要派生新的子类呢?不仅保证子类是一种特殊的父类,而且需要具备以下两个条件之一。

        1)子类需要额外增加属性,而不仅仅是属性值的改变

        2)子类要增加自己独有的行为方式(包括增加新的方法和重写父类的方法)

        到底该用继承还是改用组合呢?继承是对已有的类进行一番改造,以此获得特殊的版本,换而言之,就是将一个较为抽象的类改造成适用于某些特定需求的类。如果两个类是整体、部分的关系,就应该采用组合关系来实现复用,例如人和手臂。总之,继承要表达的是一种“is a”的关系。而组合表达的是(has a)的关系。

           

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324536538&siteId=291194637