封装
定义
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
示例
class Person{
private String name ;//设置私有属性,
//让外部不能通过"对象.属性名“的方式直接访问。
public Person() {
}
public String getName() {//但是给外部以一定的通道来访问该属性,
//可以在此方法中加入一些验证来达到保护属性的目的。
return name;
}
public void setName(String name) {
this.name = name;
}
}
为什么这么做?
- 提高程序安全性,保护了数据;
- 隐藏代码的实现细节;
- 统一接口;
- 提高系统的可维护性。
相关的点
修饰符 | 类内部 | 同一包下 | 子类 | 任何地方 |
---|---|---|---|---|
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
记忆
属性私有,get()/set()。
高内聚,低耦合。
继承
定义
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
示例
public class Demo01 {
public static void main(String[] args) {
Teacher teacher = new Teacher();
int money = teacher.money;//子类可以拥有父类的属性 获得100
teacher.say();//也可以调用父类的方法 打印"say something"
}
}
class Person{
private String name ;
public int money = 100;
public Person() {
}
public String getName() {
return name;
}
public void say(){
System.out.println("say something");
}
}
class Teacher extends Person{
}
记忆
关键字extends(扩展)
Java中只有单继承,无多继承
一般情况下,属性私有,方法公有
其他相关的点
Object类
所有的类都默认继承自Object类,任何类被定义后即便什么内容都不写也可以调用toString()、equals()、getClass()等许多Object类的方法。
tips:Ctrl+H打开Hierarchy列表。
super&构造器
public class Demo01 {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.printName("传入的名字");
}
}
class Person{
public String name = "人" ;
public int money = 100;
public Person() {
System.out.println("调用了Person的构造方法");
}
public String getName() {//但是给外部以一定的方法来获得该属性,可以在此方法中加入一些验证来达到保护属性的目的。
return name;
}
public void say(){
System.out.println("say something");
}
}
class Teacher extends Person{
public String name = "老师";
public Teacher() {
//super();写与不写该行,在实例化子类时都会默认隐式调用父类的无参构造器;但定义了有参构造器后隐式无参构造器会消失,除非自己再显示定义出来。
//另①:一般,只要重写了有参构造器,隐式的无参构造器便不存在,但子类的无参构造器必须执行父类的无参构造器,所以如果重写了父类的有参构造器后,不显式地写出父类的无参构造器会报错。
//或者,也可以将子类的构造器重写为有参构造,取消其无参构造器。
//且super()要么不写,写的话必须放在子类构造器第一行,否则报错。
this("有参构造传入的name");
//另②:如果要在本类的某个构造器(比如一个无参构造器)中调用另一个构造器(比如一个有参构造)即写入"this(xxx)",这行代码也必须写在该构造器的第一行。
System.out.println("调用了teacher的构造方法");
}
public Teacher(String name){
this.name = name;
}
public void say(){
System.out.println("teacher said something");
}
public void test(){
say();//在本类中调用与父类同名的方法,此时加与不加this.调用的均是该类自身的方法。
this.say();
super.say();//加上super.后调用的则是该类的父类的方法。
}
public void printName(String name){
System.out.println(name);//打印传入的name
System.out.println(this.name);//打印此类的name
System.out.println(super.name);//打印此类父类的name
}
}
注意
- 继承是类和类之间的一种关系,除此之外,类与类之间的关系还包括依赖、组合、聚合。
- super VS this:
- super调用父类的构造器,必须在该类构造器的第一行。
- super关键字只出现在子类的方法或构造器中。
- 不能同时使用this 和 super调用构造器。
- this代表调用者本身。
- super代表父类对象的引用。
- this在不存在继承关系的代码中也可以使用。
- super只能在有继承关系的代码中使用。
- this()指本类的构造器,super()指父类的构造器。
方法重写
示例
class Person{
String name;
int age;
public void say(){
System.out.println("say something");
}
}
class Teacher extends Person{
@Override
public void say(){
System.out.println("The teacher said something");
}
}
为什么要重写?
父类的方法,子类不一定满足或不一定需要。
注意
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小,e.g. public>protected>defualt>private
- 抛出的异常范围可以被缩小但不能扩大,e.g. ClassNotFoundException<Exception
- static 方法属于类,不属于实例,不能被重写
- final 常量池中,无法被改变,不能被重写
- private 私有的方法,不能被重写
tips:Alt+insert添加重写
多态
定义
同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际对象是确定的(new XXX()),但可以指向的引用类型是不确定的(父类引用指向子类对象)。
e.g.现实中,比如我们按下 F1 键这个动作:
如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
如果当前在 Word 下弹出的就是 Word 帮助;
在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。
示例
Person person = new Person();
Person teacher = new Teacher();
Teacher teacher2 = new Teacher();
//Persond的eat()方法没有被子类重写,run()方法被子类重写了。
System.out.print("Person引用类型指向父类对象");person.run();
System.out.print("Person引用类型指向父类对象");person.eat();
System.out.print("Person引用类型指向子类对象");teacher.run();
System.out.print("Person引用类型指向子类对象");teacher.eat();
System.out.print("Teacher引用类型-->");teacher2.run();
System.out.print("Teacher引用类型-->");teacher2.eat();
//多态:方法的多态
//调用谁的方法取决于引用类型(左边),但如果方法被子类重写了,那么对象调用子类的方法。
//static 方法属于类,不属于实例,不能被重写
//final 常量池中,无法被改变,不能被重写
//private 私有的方法,不能被重写
为什么要使用多态性
作用:当把不同的子类对象都当做父类类型来看待,可以屏蔽不同子类对象之间的实现差异,从而写出通用的代码达到通用编程,以适应需求的不断变化。
记忆
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有且方法被子类重写,再去调用子类的同名方法。
注意
多态存在的条件:继承、重写、父类引用指向子类对象。
多态指的是方法的多态,属性无多态特性。