三大特性
封装
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
将需要访问属性或方法体,以类或方法的形式封装,用户想要使用只需调用即可,不需要知道内部实现机制,保护数据安全,提高代码复用率
封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
对方法的封装
-
减少冗余,提高复用
-
参数封装 对象的属性封装数据
//emp表中修改数据c public int updateEmp(Emp emp) { String sql = " update emp set ename= ?,job= ?,mgr= ?,hiredate= ?,sal= ?,COMM= ?,deptno= ? where empno = ?"; return SqlUtils.update(sql, emp.getEname(), emp.getJob(), selectEmpno(emp.getMgr_name()), new Date(emp.getHiredate().getTime()), emp.getSal(), emp.getCOMM(), DeptDao.selectByDeptno(emp.getDname()), emp.getEmpno() );
-
返回值封装:返回对象,封装返回值数据
//根据empno查询一条信息 public Emp selectByEmpno(int empno) { String sql1 = "SELECT a.empno,a.ename,a.job,b.ename mgr_name,a.hiredate,a.sal,a.COMM,dept.dname FROM emp a LEFT JOIN emp b on a.mgr = b.empno left join dept on a.deptno = dept.deptno where a.empno=?"; return SqlUtils.queryEntity(Emp.class,sql1, empno); }
对属性的封装
保证数据安全
私有化属性变量,
提供getter和setter
public class Dept {
private Integer deptno;
private String dname;
private String loc;
public Dept(Integer deptno, String dname, String loc) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public Dept() {
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
继承
子类 extends 父类,子类具有父类的非私有所有属性与方法,子类可以修改父类非final属性值和重写非final方法。
继承是单继承,但是可连续继承。
注意:父类中定义子类共有的属性与方法。继承的必须是同一类事物
继承的特性
- 子类拥有父类非 private 的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承关键字
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承 Object(这个类在 java.lang 包中,所以不需要 import)祖先类。
extends关键字
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
public class Animal {
private String name;
private int id;
public Animal(String myName, int myid) {
//初始化属性值
}
public void eat() { //吃东西方法的具体实现 }
public void sleep() { //睡觉方法的具体实现 }
}
public class Penguin extends Animal{
}
implements关键字
使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
super 与 this 关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
//animal : eat
//dog : eat
//animal : eat
final
final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
final 含义为 “最终的”。
使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:
注: final 定义的类,其中的属性、方法不是 final 的。
重写
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,抛出 IOException 异常或者 IOException 的子类异常。
方法的重写规则
- 参数列表与被重写方法的参数列表必须完全相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
- 父类的成员方法只能被它的子类重写。
- 声明为 final 的方法不能被重写。
- 声明为 static 的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个类,则不能重写该类的方法。
当需要在子类中调用父类的被重写方法时,要使用 super 关键字。
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog 对象
b.move(); //执行 Dog类的方法
}
}
动物可以移动
狗可以跑和走
重写与重载之间的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
- (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
- (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
- (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
多态
多态是同一个行为具有多个不同表现形式或形态的能力,使用不同的实例而执行不同操作.
接口的多态: 接口引用指向接口的实现类对象
继承的多态:父类的引用指向子类的实例化
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
多态成员变量:编译运行看左边;
多态成员方法:编译看左边,运行看右边
总结
特性 | 特征 |
---|---|
封装 | 封装类的内部实现机制,在不影响使用的情况下改变内部结构,也保护了数据,只讲访问方法暴露给外界。 属性封装:使用定制好的方法访问数据,加入逻辑控制,限制不合理操作保证数据安全; 方法封装:按照指定方法调用,不必关心内部实现,便于使用修改,增强可维护性。 参数封装 参数用对象的属性来封装 返回值封装:返回对象,封装返回值数据 |
继承 | 子类继承父类,具备父类拥有的属性和方法,并扩展新的属性和方法。 子类通过extends继承父类,父类通过使用private来定义不被继承的属性或方法, 定义final来保证不被修改或重写的属性和方法。 单继承,可连续继承 |
多态 | 俩个类存在继承关系,存在方法重写,在调用时有父类引用指向子类对象。 多态成员变量:编译运行看左边; 多态成员方法:编译看左边,运行看右边 方便功能的扩展 接口的多态: 接口引用指向接口的实现类对象 继承的多态:父类的引用指向子类的实例化(上下转型) |