目录
一:封装
1.封装的概念
2.访问限定符
3.封装扩展包
二:继承
1.概念
2.语法
3.父类成员的访问
4.super关键字
5.子类构造方法
6.super和this
7.继承方式
8.final关键字
9.继承和组合
三:多态
1.概念
2.实现条件
3.重写
4.向上转型和向下转型
5.避免在构造方法中调用重写的方法
(1)定义:用关键字private对类的成员进行修饰,不透露细节,只是对外提供接口
(2)意义:可以隐藏细节,保证安全性
(1)Java中主要通过类和访问修饰限定符来实现封装:类可以将数据以及封装的方法结合在一起,而访问修饰限定符用来控制方法或者字段能否直接在类外使用。Java提供了4中访问限定符。
(2)
public:权限最大
范围 | private | default | protected | public |
同一个包中的同一类 | √ | √ | √ | √ |
同一个包中的不同类 | √ | √ | √ | |
不同包中的子类 | √ | √ | ||
不同包中的非子类 | √ |
(1)为了更好的管理类,把多个类放在一起称为一组,称为软件包(有点类似于目录)
(2)包是对类,接口等的封装机制的体现,是一种对类或接口等很好的组织方式;在同一工程中允许存在相同名称的类,只要处在不同的包中即可
(3)Java中提供了很多现成的类供我们使用,例如Date类:可以使用java.util.Date导入java.util这个包中的Date类
(4)常见的包
1)java.lang:系统常用的基础类(String、object),从JDK1.1后自动导入
2)java.lang.reflect:java反射编程包
3)java.net:进行网络编程开发包
4)java.sql:进行数据库开发的支持包
5)java.util:是java提供的工具程序包。(集合类)
6)java.io:I/O编程开发包
(1)继承机制:是面向对象程序设计的可以使代码复用的最重要的手段,他允许在保持原有特性的基础上进行扩展,增加新功能,产生新的类,称为子类或者派生类
(2)继承呈现了面向对象程序设计的层次结构,体现了从简单到复杂的认知过程。
(3)继承主要解决的问题:共性的抽取,实现代码的复用
(4)父类:一定是子类的共性
Java中表示类之间继承关系,用关键字extends:
修饰符 class 子类 extends 父类{
}
Animal.java
Dog.java
TestA.java//测试类
注意:
1)子类会将父类中的成员变量或者成员方法继承到子类中
2)子类继承父类之后,必须要添加自己子类自己特有的成员,体现出和基类(父类、超类)的不同,否则就没必要继承了
(1)子类中访问父类的成员变量
1)子类和父类不存在同名的成员变量
2)子类和父类成员变量同名
3)总结:
在子类方法中或者通过子类对象访问成员时:
//如果访问的成员变量子类自己有,优先访问自己的成员变量
//如果访问的成员变量子类自己无,则访问父类继承下来的,如果父类也没有定义,则编译报错
//如果访问的成员变量与父类中的成员变量同名的时候,则优先访问自己的
//成员变量访问遵循就近原则,自己有优先自己的,没有再在父类中找
(2)子类中访问父类的成员方法
1)成员方法名字不同
总结: 成员方法没有同名时,在子类方法中或者通过子类访问方法时,则优先访问自己的,自己没有是再在父类找,如果父类没有则报错
2)成员方法名字相同
public class Base {
public void methodA() {
System.out.println("Base中的methodA()");
}
public void methodB() {
System.out.println("Base中的methodB()");
}
}
class Derived extends Base{
public void methodA(int a){
System.out.println("Derived中的methodA()");
}
public void methodB(){
System.out.println("Derived中的methodB()");
}
public void methodC(){
methodA();//没有传参,访问父类中的methodA()
methodA(1);//传递int参数,访问子类的methodA()
methodB();//直接访问子类的
}
}
总结:通过子类对象访问父类和子类中不同方法时,优先在子类中找,找到则访问,否则在服了中找,找到则访问,否则编译报错
通过子类对象访问父类对象与子类同名的方法时,如果方法重载了,根据调用方法传递的参数确定合适的方法访问,如果没有则报错
(1)问题:如果存在同名情况时,偏要访问父类的成员呢?这时就使用super关键字
(2)super作用:在子类方法中访问父类的成员
(3)super在当前类使用,则当前类一定是子类;只能在非静态方法中使用
eg:Student(String id, String name, String birth,String department) 是Undergraduate的父类
(1)子类对象构造时,需要调用父类的构造方法,然后再执行子类的构造方法
(2)子类对象中成员是有两部分组成的,父类继承下来的以及子类自己新增的成员。先调用父类的构造方法,将从父类继承下俩的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增的成员初始化完成
(1)相同点:
1)都是关键字
2)只能在类的非静态方法中使用,用来访问非静态的成员变量和成员方法
3)在构造方法调用时,只能是构造方法的第一行,且不能同时存在
(2)不同点:
1)this代表是当前对象的引用,,super相当于是从子类对象中从父类继承下来的部分成员的引用
2)this用来访问本类的方法和属性,super用来访问父类的方法和属性
3)在构造方法中,this(...)用于调用本类的构造方法,super(...)用来调用父类的构造方法,两种不同的调用不能同时存在于构造方法中
4)构造方法中一定会存在super(...)的调用,用户没写编译器自动添加,而this(...)用户不写则没有
(1)Java只支持单继承,支持多层继承,支持不同类继承同一个类,但是不支持多继承,
(1)final可以用来修饰变量,表示变量不可以修改
(2)final可以修饰类,表示该类不能被继承
(3)final可以修饰方法,表示该方法不能被重写
(1)和继承类似,组合也是一种表达类之间关系的方式,也能达到代码复用的效果
(2)继承是is-a 的关系,而组合是 has-a的关系
简单来说就是多种形态;复杂点来说就是为了完成某个任务,当不同的对象去完成会产生不同的状态
(1)必须有继承
(2)子类必须对父类的方法进行重写
(3)通过父类的引用调用父类的方法
多态体现:在代码运行时,当传递不同的类对象时,会调用对应类中的方法
(1)重写:也称覆盖。重写是子类对父类非静态,非private修饰的,非final修饰的,非构造方法等的实现过程进行重写,方法名相同,参数列表相同,返回值也相同
(2)重写的好处就是在于子类可以根据需要,定义特定于自己的行为。也就是说子类可以根据需要实现父类的方法
(3)重写(override)和重载(overload)
区别点 | 重写 | 重载 |
参数列表 | 不能修改 | 必须修改 |
返回类型 | 不能修改(除非为父子关系) | 可以修改 |
访问限定符 | 可以降低限制 | 可以修改 |
(4)方法重载是一个类的多态性表现,而方法重写是子类对父类的一种多态性表现
(5)重写的设计原则:
对于已经投入使用的类,尽量不要修改。最好的方式是:重新定义一个新的类,来重复利用其中的共性的内容,并且添加或者改动新的内容
(1)向上转型:就是创建一个子类对象,将其当成父类使用
语法格式:
父类类型 对象名 = new 子类类型();
eg:Animal a = new Cat();//是小范围到大范围的转换
优点:让代码更简单灵活
缺点:不能调用到子类特有的方法
(2)向下转型:将父类引用在还原为子类对象
语法格式:
子类类型 对象名 = (子类类型)父类类型;
eg:Cat a = (Cat)Animal;//是大范围到小范围的转换
优点:能调用到子类特有的方法
缺点:不安全(最好使用instanceof)
class B{
public B(){
func();
}
public void func(){
System.out.println("B.func()");
}
}
class D extends B{
private int num=1;
@Override
public void func() {
System.out.println("D.func() "+num);
}
}
public class Test {
public static void main(String[] args) {
D d=new D();
}
}
总结:"用尽量简单的方式使对象进入可工作状态",尽量不要在构造方法中调用方法(如果这个方法被子类重写,就会触发动态绑定,但是此时子类还没有完成构造),可能会出现一些隐藏的极难发现的问题。