Java 面向对象的特征(一)
一、封装
封装指的是把数据(属性)和对数据的操作(方法)封装在一起,只有通过特定的操作才能够访问到内部数据。
作用:
- 隐藏具体的实现细节,只要程序员了解细节即可;
- 可以对数据进行验证,使用更加安全,防止不合理的数据。
实现:
- 将属性私有化,不能直接对数据进行访问;
- 对私有的属性提供get方法,对权限进行判断,用于获取属性具体的值;
- 对私有的属性提供set方法,用于对属性的合理性进行判断并给属性赋值。
ps.以上在设置get和set方法的时候可以在当中添加不同的业务逻辑,可以更好地保护数据。
例如以下的封装类:
public class House {//房子中有门、窗户这两个属性private String door; private int window;public House() { //空参构造}public House(String door, int window) { //三个参数的构造器this.door = door;this.window = window;}public String getDoor() { //门属性的get方法return door;}public void setDoor(String door) { //门属性的set方法this.door = door;}public int getWindow() { //窗户属性的get方法return window;}public void setWindow(int window) { //窗户属性的set方法this.window = window;}
}
但是以上的类封装中的构造器可能会使封装的功能失效,可以在构造器中调用相应的set方法依然可以保护数据。下面在构造器其中调用set方法给window赋值,并且set方法中判断是否符合一个房子中有超过0个窗户和不超过4个窗户的限制来保证数据的合理性。
在window的set方法来保证数据的合理性:
public void setWindow(int window) { //窗户属性的set方法if (window > 0 && window < 5) { //符合就给属性赋值this.window = window;} else { //不符合就给出提示System.out.println("窗户数量设置不正确!");}}
在构造器中调用window的set方法来赋值:
public House(String door, int window) { //三个参数的构造器this.door = door;setWindow(window); //使用set方法来对window赋值
}
二、继承
原因:当有多个类具有相同的属性和方法的时候,可以把这些属性和方法拿出来放到同一个父类中,再由多个类来继承这个父类,即子类,子类中具备了父类中的属性和方法,同时多个子类也减少了很多内容,提高了代码的复用性,也使代码更加简洁。
特点:
- 子类会具有父类的属性和方法;
- 父类可以叫父类,基类,超类;
- 子类可以叫子类,导出类,派生类。
好处:
- 代码的复用性大大提高;
- 代码的可维护性和可拓展性更好。
细节:
Ⅰ.子类不能直接访问父类中的私有属性和方法,需要通过共有的方法来访问;
如以下例子:
public class Father {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}class Son extends Father {public void printName() {System.out.println(getName()); //当子类调用父类中的方法的时候需要使用get方法}
}
Ⅱ.子类在创建新的对象的时候,会先调用父类的无参构造器完成对父类的初始化,然后再调用子类的构造器,完成子类的初始化;(子类构造器中会默认有一个super( ))会默认调用父类的构造器,写不写都会有;
例如以下例子:
public class Father {public Father() {System.out.println("我是父类的构造器");}public static void main(String[] args) {Son son = new Son();}
}class Son extends Father {public Son() {//这里即使不写会默认有一个super();System.out.println("我是子类的构造器");}
}
运行的结果为:
Ⅲ.如果父类中没有提供无参构造器,那么在子类的构造器中必须使用super指定调用哪个构造器,否则会无法通过编译。
例如以下例子:
public class Father {private String name;public Father(String name) { //父类中只有带参构造this.name = name;}
}class Son extends Father {public Son(String name) {super(name); //必须使用super来指定构造器否则就会报错}
}
Ⅳ.如果要调用父类中的特定的构造器,需要使用super显式地调用一下super( );
Ⅴ.super()的使用必须放在第一行,super()只能在构造器中使用,不能在成员方法中使用;
例如以下例子:
public class Father {public Father() { //父类的构造器System.out.println("父类的构造器");}
}class Son extends Father {public Son() {super(); //super()在这里必须放在第一行,否则无法通过编译System.out.println("子类的构造器");}
}
Ⅵ.super和this都只能放在构造器的第一行,所以这两个不能放在同一个构造器中使用;
Ⅶ.Java所有的类都是object的子类;
如以下例子:
public class Test {public static void main(String[] args) {Test test = new Test();System.out.println(test instanceof Object);}
}
运行结果如下:
结果为true,因此说明test作为一个Test类型的类,也是Object的子类。
Ⅷ.父类构造器的调用不仅限于直接父类,会一直向上追溯到object类;
Ⅸ.Java是单继承机制,即一个子类只能继承一个父类;
Ⅹ.不能滥用继承机制,要满足is-a的关系,而不是like-a的关系。
比如狗、猫、青蛙都是动物,是is-a的关系,所以可以满足继承的机制;而如果说天上的云像棉花糖、像小鸡,是like-a的关系,那么就不能满足继承关系。