1. 封装
1.1 目的
用户不必了解方法内部的细节,知道如何使用即可,从而提高系统的可扩展性和维护性。
高内聚:类的内部数据操作细节由自己完成,不允许外部干涉;
低耦合:仅对外暴露少量方法用于使用;
1.2 封装举例
封装前:
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.name = "张三";
p.age = -10;
p.show();
}
}
class Person{
String name;
int age;
public void show() {
System.out.println("name = " + name + ",age = " + age);
}
}
// 输出:name = 张三,age = -10
没有封装的情况下,年龄可以任意赋值,当为负数时显然违背常理,存在问题;接下来对年龄字段进行封装
封装后:
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.name = "张三";
// p.age = -10;
p.setAge(-10);
p.show();
}
}
class Person{
String name;
private int age;
public void setAge(int a) {
if(0 < a && a < 150) {
age = a;
}else {
System.out.println("输入的年龄不合法!");
}
}
public void show() {
System.out.println("name = " + name + ",age = " + age);
}
}
// 输出:输入的年龄不合法!name = 张三,age = 0
※ 封装主要体现在:private 修饰,不让外界访问直接访问;设置set/get方法,防止变量乱赋值。
2. 继承
2.1 目的
提高代码复用性;
便于扩展(在父类中添加功能);
2.2 体现形式
class A extends B{}
A为子类,subclass
B为父类,superclass
类的继承使用关键字extends,通过extends 可以实现两个类之间的继承关系;
继承后,子类可以获取父类中的属性和方法,私有成员子类是不可以直接使用的;(私有成员:被private 所修饰)
子类中可以实现功能的扩展;
Java 中不允许多继承;(is a)
可以间接继承,子类拥有所有父类属性和方法;
2.2 继承举例
public class Person {
String name;
int age;
public Person() {}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("吃饭");
}
public void run() {
System.out.println("跑步");
}
}
没有继承:
public class Student {
String name;
int age;
String major;
public Student() {}
public Student(String name,int age,String major) {
this.name = name;
this.age = age;
this.major = major;
}
public void eat() {
System.out.println("吃饭");
}
public void run() {
System.out.println("跑步");
}
public void study() {
System.out.println("学习");
}
}
继承:
public class Student extends Person{
// String name;
// int age;
String major;
public Student() {}
public Student(String name,int age,String major) {
this.name = name;
this.age = age;
this.major = major;
}
// public void eat() {
// System.out.println("吃饭");
// }
//
// public void run() {
// System.out.println("跑步");
// }
public void study() {
System.out.println("学习");
}
}
2.3 方法的重写(覆盖)
1)继承关系
2)3个相同(方法名、参数列表、返回值类型)
3)修饰符 子>=父
4)异常(编译异常) 子<=父
重写是语法,覆盖是效果
2.4 子类中的构造函数
this(); 调用子类构造函数
super(); 调用父类构造函数
传递什么参数,就调用与之对应的构造函数。
在子类对象进行初始化时,父类的构造函数也会执行,因为子类构造函数默认第一行有一条隐式的语句super() 会调用父类无参的构造函数,而且子类中所有的构造函数默认第一行都是super();
3. 多态
3.1 特点
父类声明子类创建
父类、子类都声明的方法,调用的是子类中重写的方法;(编译看左边,执行看右边)
子类中追加的父类没有的方法,无法调用;
多态中,属性调用的是子类中的属性;(父类的方法,子类的属性)
(多态运行时,在栈中同时创建子类和父类两个对象)
3.2 多态举例
Person p1 = new Person();
p1.eat();
p1.run();
Student s = new Student();
s.eat();
// 多态,父类的引用指向子类对象
Person p2 = new Student();
p2.eat();
3.3 多态应用
// 父类
public class Person {
public void eat() {
System.out.println("吃饭");
}
public void run() {
System.out.println("跑步");
}
}
// 学生子类
public class Student extends Person{
public void eat() {
System.out.println("学生吃饭");
}
public void run() {
System.out.println("学生跑步");
}
}
// 老师子类
public class Teacher extends Person{
public void eat() {
System.out.println("老师吃饭");
}
public void run() {
System.out.println("老师跑步");
}
}
没用多态:
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.showStudent(new Student());
t.showTeachert(new Teacher());
}
public void showStudent(Student st) {
st.eat();
st.run();
}
public void showTeachert(Teacher te) {
te.eat();
te.run();
}
}
输出:
学生吃饭
学生跑步
老师吃饭
老师跑步
多态:
public class Test {
public static void main(String[] args) {
Test t = new Test();
//t.showStudent(new Student());
//t.showTeachert(new Teacher());
t.show(new Student());
t.show(new Teacher());
}
// public void showStudent(Student st) {
// st.eat();
// st.run();
// }
// public void showTeachert(Teacher te) {
// te.eat();
// te.run();
// }
public void show(Person p) {
p.eat();
p.run();
}
}
没有多态的话,需要制造很多的重载方法
补充:
1)参数为Object 类型的方法,即使用的多态技术,传递Object 的子类即可;
2)DB连接Connection 是java 定义的一个接口,各个数据库厂商根据该标准实现对应的数据库连接方法,用户在使用时创建对应厂商的数据库连接对象即可使用;
java.sql.Connection;
public interface Connection extends Wrapper, AutoCloseable { …}