封装
封装指的是将类的复杂的细节隐藏起来,只暴露一些简单的接口。封装便于调用者调用,便于修改内部代码,提高可维护性,可进行数据完整性检测,保证数据的有效性
下表为关键字及其访问权限
关键字 | 同一个类 | 同一个包 | 子类 | 所有类 |
---|
private | √ | | | | default | √ | √ | | | protected | √ | √ | √ | | public | √ | √ | √ | √ |
类的属性一般用private修饰(除非确定会让其子类继承),通过 get/set方法来访问或操作这些属性
一些只用于本类的辅助性方法用private修饰,希望其它类可以调用的方法用public修饰
继承(extends)
继承可以提高代码的复用性,利用组合可以更好的实现代码复用
Java中使用extends关键字实现继承,子类继承父类,可以得到父类的所有属性和方法(尽管有些元素是private的,但子类仍可以拥有,但是不可以访问)
Java中只有单继承,多继承可以通过接口来实现
如果定义一个类时没有调用extends继承其他类,那默认该类继承了Object类,也称Object为祖先类
例如:
class Hello{
class Person{
public String name;
private int age;
public String getName(){
return this.name;
}
private int getAge(){
return this.age;
}
}
class Student extends Person{
}
}
重写(overwrite)
-
在子类继承父类的方法后,若该方法并不适宜当前的子类,则可以重写这个方法 -
重写时需要方法名、参数列表和返回值都与父类的一致 -
重写方法不能使用比被重写方法更严格的权限控制 -
当我们调用一个对象方法时,优先从当前类开始查找,若没有再到父类查找 -
用private、static、final关键字修饰的方法不能重写
例如:
class Hello{
class Person{
public String name;
private int age;
public String getName(){
return this.name;
}
private int getAge(){
return this.age;
}
}
class Student extends Person{
public String getName(){
return "张三";
}
public String getName(String name){
this.name = name;
return this.name;
}
}
}
super关键字
首先可以将super笼统地理解为功能与this差不多的关键字,但是this指向的是当前对象,而super指向的则是该对象的父类。可以通过super去调用父类的属性或方法
例如:
class Hello{
class Person{
public String name;
public int age;
public String getName(){
return this.name;
}
}
class Student extends Person{
public int number;
public String getName(){
return super.getName();
}
}
}
this可以调用本类的构造器,同样的super也可以调用父类的构造器,但与this不同的是,在子类的构造器中,尽管没有使用super去调用父类的构造器,但程序会默认调用父类的空构造器,这说明了在初始化子类时,肯定会先初始化其父类。这也带来了一个bug:如果父类编写了构造器并且没有编写空构造器,同时子类的构造器中没有调用父类的构造器则会报错。
例如:
class Hello{
class Person{
String name;
int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
}
class Student(){
int number;
public Student(String name, int age, int number){
super(name, age);
this.number = number;
}
}
}
多态(polymorphism)
多态为代码的编写带来了很大的灵活性,实现多态的要求有三个:继承、重写、父类引用指向子类
用一个例子来解释多态
class Hello{
public statci void main(String[] args){
Student student = new Student();
Teacher teacher = new Teacher();
someoneSay(student);
someoneSay(teacher);
}
public static void someoneSay(Person person){
person.say();
}
class Person{
String name;
int age;
public void say(){
System.out.println("我是人类");
}
}
class Student extends Person{
public void say(){
System.out.println("我是学生");
}
}
class Teacher extends Person{
public void say(){
System.out.println("我是老师");
}
}
}
注意:在父类引用指向子类的情况下,虽然创建的真实对象为子类的对象,但是其包含的属性和方法只有在父类中存在的属性和方法,并没有子类所特有(增加)的属性和方法
静态绑定与动态绑定
在类的编译期间,Jvm会找出该类的不可能存在多态情况的方法将其加载至该类的静态绑定区,不可能存在多态的方法有:private static final constructor(构造方法)
而其他方法因为有多态的嫌疑则加载至该类的动态绑定区
在调用该类的某个方法时,程序先在静态绑定区寻找该方法是否存在,若存在则直接运行,若不存在则再去动态绑定区寻找,找到后再确定调用该方法的真实类(可能是父类引用子类的情况)中的动态绑定区是否有该方法,若有则执行真实类的方法,没有则执行原先找到的方法。当然若静态绑定区和动态绑定区都没找到该方法就会报错了
|