面向对象
封装的优点:
1、良好的封装能够减少耦合。
2、类内部的结构可以自由修改。
3、可以对成员变量进行更精确的控制。
4、隐藏信息,实现细节。
封装实现的步骤:
1、修改属性的可见性来限制对属性的访问(一般限制为private)
例:public class Person{
private String name;
private int age;
}
2、对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,对于私有属性的访问
一般用getxx()和setxx()方法来获取。
例:
public class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
this关键字是为了解决实例变量和局部变量之间的同名问题。
继承:
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。
结构:
class 父类{
}
class 子类 extends 父类{
}
继承的使用规则:
1、在java中是单继承,但可以通过接口( implements)实现多继承。
2、子类可继承父类非私有的属性和方法,不能继承构造方法。
3、当实例化子类时,先执行父类的构造方法,再执行子类的构造方法。
4、当父类的方法无法满足子类需要时,子类可以重写父类方法。
5、当类使用final关键字修饰时,该类不能被继承;
用于修饰方法,该方法不能被子类重写。
6、在子类中,使用super关键字表示父类对象,可以用在非静态方法中;
super()表示父类构造器(构造方法或构造函数),只能用在子类的构造器中,并且只能用在第一行;
7、this代表子类对象,可以使用在子类的非静态方法中;this()表示子类的构造器,只能用在子类的构造其中,并且是在构造器的第一行;不能和super()同时出现。
例:
class Animal{
void go(){
System.out.println("animal go");
}
}
class Dog extends Animal{
void go(){
//调用父类方法
super.go();
}
}
//驱动函数
public static void main(String[] args){
Dog dog=new Dog();
dog.go();
}
重写的规则:
1、参数列表、方法名和返回值类型要和父类中的方法保持一致。
2、重写方法的访问权限要大于或等于父类的方法。
3、当父类的方法使用static关键词修饰时,可以被继承,不能被重写,但是可以在子类中重写声明。
4、当父类的方法使用final关键词修饰时,可以被继承,不能被重写。
5、构造方法既不能被继承、也不能被重写(如果不能继承一个方法,则不能重写这个方法)。
6、重写方法可以抛出任意的非强制性异常,如果父类方法中抛出了异常,子类中的重写方法抛出异常的范围要小于等于父类。
7、(排除final和static关键字的情况下)
如果在同包下,子类可以重写父类的非私有的方法;
不在同包下,子类只能重写父类的public和protected修饰的方法;
重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则
- 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
重写与重载之间的区别
区别点 |
重载方法 |
重写方法 |
参数列表 |
必须修改 |
一定不能修改 |
返回类型 |
可以修改 |
一定不能修改 |
异常 |
可以修改 |
可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 |
可以修改 |
一定不能做更严格的限制(可以降低限制) |
多态实现的方法:
1、继承
2、方法重写
3、父类引用指向子类对象(向上转型)
例:
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
4、父类引用调用子类重写的方法,指向的是重写方法。