面向对象三大特征:继承、封装、多态 (泛型)

封装封装是一个概念,它的含义是把方法、属性、事件集中到一个统一的类中,并对使用者屏蔽其中的细节问题。数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。

比如我们将一个房子看做是一个对象,里面的漂亮的装饰,如沙发、电视剧、空调、茶桌等等都是该房子的私有属性,但是如果我们没有那些墙遮挡,是不是别人就会一览无余呢?没有一点儿隐私!就是存在那个遮挡的墙,我们既能够有自己的隐私,而且我们可以随意的更改里面的摆设而不会影响到其他的。但是如果没有门窗,一个包裹的严严实实的黑盒子,又有什么存在的意义呢?所以通过门窗别人也能够看到里面的风景。所以说门窗就是房子对象留给外界访问的接口。

使用封装的好处:

1、类内部的结构可以自由修改。

2、隐藏信息,实现细节。

3、可以对成员进行更精确的控制。(如果输入有问题的时候,可以在调用的时候进行判断。)

4,封装确实可以使我们容易地修改类的内部实现,而无需修改使用了该类的客户代码。

一般我们写的类的属性就是用的封装的思想,里面的属性都是private,比如:

public class Husband {  
     private String name ;  
     private String sex ;  
     private int age ;  
     private Wife wife; 
} 

然后外部通过getter和setter方法去访问这个类里面的数据,

Husband husband=new Husband();

husband.setName(xx);//更改Husband类里面的name的时候用,

husband.getName();//获得husband对象里面的name

01.public class Husband {  
02.      
03.    /* 
04.     * 对属性的封装 
05.     * 一个人的姓名、性别、年龄、妻子都是这个人的私有属性 
06.     */  
07.    private String name ;  
08.    private String sex ;  
09.    private int age ;  
10.    private Wife wife;  
11.      
12.    /* 
13.     * setter()、getter()是该对象对外开发的接口 
14.     */  
15.    public String getName() {  
16.        return name;  
17.    }  
18.  
19.    public void setName(String name) {  
20.        this.name = name;  
21.    }  
22.  
23.    public String getSex() {  
24.        return sex;  
25.    }  
26.  
27.    public void setSex(String sex) {  
28.        this.sex = sex;  
29.    }  
30.  
31.    public int getAge() {  
32.        return age;  
33.    }  
34.  
35.    public void setAge(int age) {  
36.        this.age = age;  
37.    }  
38.  
39.    public void setWife(Wife wife) {  
40.        this.wife = wife;  
41.    }  
42.}  


继承:如果两个类存在继承关系,则子类会自动继承父类的方法和变量,在子类中可以调用父类的方法和变量,如果想要在子类里面做一系列事情,应该放在父类无参构造器里面。java中,只允许单继承,也就是说一个类最多只能显示地继承于一个父类。但是一个类却可以被多个类继承,也就是说一个类可以拥有多个子类。

java类不允许多继承。原因:

1,当不同的父类存在相同属性方法的时候,无法判定调用哪个。

2,由于子类实例化需要调用父类的无参构造器,无法识别是那个父类的构造器,

1.子类继承父类的成员变量

  当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:

1)能够继承父类的publicprotected成员变量;不能够继承父类的private成员变量;

2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用super.属性名

2.子类继承父类的方法

  同样地,子类也并不是完全继承父类的所有方法。

1)能够继承父类的publicprotected成员方法;不能够继承父类的private成员方法;

2)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

3)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用super.方法名(形参列表)

  注意:隐藏和覆盖是不同的。隐藏是针对成员变量和静态方法的,而覆盖是针对普通方法的。隐藏:调用的时候用谁的引用,则调用谁的版本。

3.构造器

子类是不能够继承父类的构造器,但是要注意的是,

如果父类的构造器只带有参数的,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表,如果不想用super调用,那父类一定要有一个显示声明的无参构造器。

如果父类有无参构造器,则在子类的构造器中用super关键字调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。

4.super

super主要有两种用法:

1super.成员变量/super.成员方法;

2super(parameter1,parameter2....)

  第一种用法主要用来在子类中调用父类的同名成员变量或者方法;第二种主要用在子类的构造器中显示地调用父类的构造器,要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句

比如:下面的类DBHelper继承与SQLiteOpenHelper,DBHelper类里面的构造器调用了父类的构造器,

面向对象三大特征:继承、封装、多态 (泛型)_第1张图片

5.重写父类的方法:

1)子类必须与父类使用相同的方法名、参数列表,

2)子类的访问权限不能比父类的更严格

3)子类返回值类型<=父类的返回值类型的范围

4)如果父类使用static修饰,则子类必须用static

5)如果父类的方法用了final,则子类不能重写该方法

如果父类必须要自己的每一个子类都重写自己的某个方法,则把父类的该方法写成抽象的方法,则子类继承的时候自动的重写该方法。

例如:

面向对象三大特征:继承、封装、多态 (泛型)_第2张图片

上面的类是为了之后写的BaseAdapter子类都继承与ParentAdapter,这样就不用再去重写BaseAdapter里面的getItemId(),getCount(),getItem()这三个方法,只需要重写getView()就可以了,本来把getView()方法定义成abstarct就可以了,但是因为getView是重写的,所以我们只能更改方法体里面的,其他都不能更改,包括返回值,关键字,所以把ParentAdapter类定义成抽象的,这样子类都必须重新getView().

  重载:

在同一个类中存在同名的方法

1)重载方法名必须形同

2)参数列表必须不同

  重构


重构就是通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。总的来说就是代码优化

 

多态:多态性是指相同的操作可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。

多态:父类型的引用可以指向子类型的对象。


多态,是面向对象的程序设计语言最核心的特征。多态,意味着一个对象有着多重特征,可以在特定的情况下,表现不同的状态,从而对应着不同的属性和方法。从程序设计的角度而言,多态可以这样来实现(以java语言为例):

  public interface Parent//父类接口{
    public void simpleCall();
  }

 public class Child_A implements Parent{
    public void simpleCall();{
    //具体的实现细节;
    }
  }
 
  public class Child_B implements Parent{
    public void simpleCall();{
    //具体的实现细节;
    }
  }

然后,我们就可以看到多态所展示的特性了:
Parent pa = new Child_A();pa.simpleCall()则显然是调用Child_A的方法;
Parent pa = new Child_B();pa.simpleCall()则是在调用Child_B的方法。
所以,我们对于抽象的父类或者接口给出了我们的具体实现后,pa 可以完全不用管实现的细节,只访问我们定义的方法,就可以了。事实上,这就是多态所起的作用,可以实现 控制反转这在大量的J2EE 轻量级框架中被用到,比如 Spring的依赖注入机制。







泛型:

泛型是对数据类型的抽象,体现了参数的多态性


(1)定义泛型属性:

我们经常在定义一个集合的时候,还不确定是线性链表ArrayList还是LinkedList,或者是其他,这个时候,在类里面定义的时候我们多用泛型;List list;

在使用的时候,list=new ArrayList();

同样的,我们在定义变量的时候,为了增加代码的可扩展性,我们可以使用泛型定义,比如:ArrayList list;

在使用的时候,根据需要传入对象,比如我现在需要创一个String类型的list,那么list=new ArrayList();



(2)定义泛型类

是在实例化类的时候指明泛型的具体类型;

这个时候用的T也是用的多态的思想,因为我们不知道子类会传什么对象过来,同时这样写也增加了子类的扩展性,

子类就可以像下面这样根据自己的需要传入对象:





(3)定义泛型方法:

是在调用方法的时候指明泛型的具体类型。

面向对象三大特征:继承、封装、多态 (泛型)_第3张图片

图片信息来源:http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html

定义泛型方法时,必须在返回值前边加一个,来声明这是一个泛型方法,


/**
 * 将对象转化为String
 *
 * @param object
 * @return
 */

public static  <T>  String objectToString(T object) {
    if (object == null) {
        return "Object{object is null}";
    }
    if (object.toString().startsWith(object.getClass().getName() + "@")) {
        StringBuilder builder = new StringBuilder(object.getClass().getSimpleName() + " { ");
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            boolean flag = false;
            for (String type : types) {
                if (field.getType().getName().equalsIgnoreCase(type)) {
                    flag = true;
                    Object value = null;
                    try {
                        value = field.get(object);
                    } catch (IllegalAccessException e) {
                        value = e;
                    } finally {
                        builder.append(String.format("%s=%s, ", field.getName(),
                                value == null ? "null" : value.toString()));
                        break;
                    }
                }
            }
            if (!flag) {
                builder.append(String.format("%s=%s, ", field.getName(), "Object"));
            }
        }
        return builder.replace(builder.length() - 2, builder.length() - 1, " }").toString();
    } else {
        return object.toString();
    }
}

上面定义了方法,在使用的时候:

ActiveJumpEntity entity;
entity = new ActiveJumpEntity(101, "13991193813", "111", "11",  "重庆", "南岸区", "重庆市南岸区四公里");
String string = objectToString(entity);

调用的时候,传入的是entity,也就是ActiveJumpEntity的对象。这样的写法,便于扩展,这样一个方法可以用在很多不同的对象上面,比如上面这个方法,是把一个类对象转化成String,便于我们打印Log,如果直接用Log打印传入这个entity,那么打印的是entity的地址,而我们的想法是看到对象内部的具体值,所以就用泛型方法的思想写这样的一个方法objectToString() ,之后就可以传入不同的类,扩展性很强。


网友说多态与泛型没有关系,不过我暂时还不能理解。

 

你可能感兴趣的:(java)