封装的概念
1.将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作与访问。
2.尽可能的把东西藏起来,对外提供便捷的接口。
封装的两个大致原则
1.把尽可能多的东西藏起来,对外提供便捷的接口;
2.把所有的属性藏起来;
如何实现封装(三步走)?
1.修改属性可见性(设为private,防止错误的修改)
2.创建共有getter,setter方法(用于属性的读写)
3.在getter,setter语句中加入属性控制语句(对属性值的合法性进行判断)
封装的好处
1.便于使用者正确使用系统,防止错误修改属性
2.有助于系统之间的松耦合,提高系统独立性
3.提高软件的可重用性
4.降低了构建大型系统的风险
包
包的作用
1.允许类组成较小的单元(类似文件夹),易于找到和使用相应的文件
2.防止命名冲突区分名字相同的类
3.有助于实施访问权限控制
包命名规范
包名由小写字母组成,不能以圆点开头或结尾
package mypackage;
包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名
package net.javagroup.mypackage;
包名后续部分依不同机构内部的规范不同而不同
package net.javagroup.research.powerproject;
使用包的注意事项
1.一个类同时引用了两个来自不同包的同名类必须通过完整类名来区分
2.每个包都是独立的,顶层包不会包含子包的类package和import的顺序是固定的
(1)package必须位于第一行(忽略注释行)
(2)只允许有一个package语句
(3)其次是import
(4)接着是类的声明
类的访问修饰
public修饰符:公有访问级别
默认修饰符:包级私有访问级别
类成员的访问修饰(不同包内只有public可以被访问)
static修饰符
static可以用来修饰
成员变量:
静态变量(类变量),可以直接通过类名访问
1.被static修饰的变量
2.在内存中只有一个拷贝
3.类内部,可在任何方法内直接访问静态变量
4.其他类中,可以直接通过类名访问
static变量的作用:
(1)能被类的所有实例共享,可作为实例之间进行交流的 共享数据
(2)如果类的所有实例都包含一个相同的常量属性,可把 这个属性定义为静态常量类型,从而节省内存空间
(实例变量)
1.没有被static修饰的变量
2.每创建一个实例,就会为实例变量分配一次内存,实例变量 可以在内存中有多个拷贝,互不影响
成员方法:
静态方法,可以直接通过类名访问(静态方法必须被实现)
1.静态方法中不能使用this和super
2.不能直接访问所属类的实例变量和实例方法
3.可直接访问类的静态变量和静态方法
(实例方法:通过实例访问)
可直接访问所属类的静态变量、静态方法、实例变量和实例 方法
代码块:
静态代码块,当Java虚拟机加载类时,就会执行该代码块
如果有多个静态块,按顺序加载每个静态代码块只会被执行 一次
public class StaticTest { static int num=100; static{ num+=100; System.out.println(num); } static{ num+=100; System.out.println(num); } } 二、继承
继承的概念
多个类中相同的属性和方法抽取出来放入到一个新的类中(父类), 多个类中就不需要再重复定义这些属性和方法,只需要写自己类中独有的属性和方法,使用extends关键字继承父类就可以使用父类中的属性和方法。
如何使用继承
编写父类
[访问修饰符] class Pet { //公共的属性和方法 }
编写子类,继承父类
[访问修饰符] class Dog extends Pet { //子类特有的属性和方法 }
继承是Java中实现代码重用的重要手段之一。Java中只支持单根继承,即一个类只能有一个直接父类
子类访问父类成员
1.访问父类构造方法
super(); super(name);
2.访问父类属性
super.name;
3.访问父类方法
super.print();
super关键字
(1)使用super关键字,super代表父类对象
(2)在子类构造方法中调用且必须是第一句
(3)不可以访问父类中定义为private的属性和方法
(super关键字来访问父类的成员
(1)super只能出现在子类的方法和构造方法中
(2)super调用构造方法时,只能是第一句
(3)super不能访问父类的private成员)
继承条件下的构造方法
继承条件下构造方法的调用规则
(1)子类构造方法没有通过super显式调用父类的有参构造方法,也没通过this显式调用自身其他构造方法(系统默认调用父类的无参构造方法)
(2)子类构造方法通过super显式调用父类的有参构造方法(执行父类相应构造方法,而不执行父类无参构造方法)
(3)子类构造方法通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则
理解继承
子类继承父类的什么?
(1)继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里
(2)继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里
子类可以继承父类的所有资源吗?
知识回顾
访问修饰符protected可以修饰属性和方法
本类、同包、子类可以访问
使用继承
何时使用继承?
继承与真实世界类似
符合is-a关系的设计使用继承
例如:
(1)只要说“猫是哺乳动物”,猫的很多属性、行为就不言自明了 (猫继承哺乳动物类)
(2)藏獒是一种狗(藏獒继承狗类)
继承是代码重用的一种方式
将子类共有的属性和行为放到父类中
方法重写规则
1.方法名相同
2.参数列表相同
3.返回值类型相同或者是其子类
4.访问权限不能严于父类
5.父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
6.子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
7.父类的私有方法不能被子类覆盖
8.不能抛出比父类方法更多的异常
方法重写vs方法重载
Object类被子类经常重写的方法
三、多态什么是多态
多态:同一个事物,作用条件不一样,结果不一样 多态:同一个父类引用,指向不同的子类实例,执行不同的操作 方法重写是实现多态的前提
多态实现步骤:
1)在抽象父类中定义抽象方法 2)子类继承抽象父类并重写父类中所有的抽象方法 3)测试类中创建父类引用指向不同的子类实例,父类引用调用方法,调用的是子类重写后的那些方法 向上转型(自动类型转换):父类的引用指向子类的实例 向下转型(强制类型转换):子类的引用指向父类的引用
public static void main(String[] args) { //创建Father类对象 //Father father = new Father();//抽象类不能实例化,因为没有意义 //向上转型,父类指向子类实例 Father father = new Son1("张三", 18, 173); father.test(); father = new Son2("李四", 25, 142); father.test(); //父类引用不能调用子类里面的方法,需要向下转型 //father.son1Method(); if(father instanceof Son2){ //向下转型:子类的引用指向父类的引用 Son2 son2 = (Son2)father; //son2.test(); son2.son2Method(); }else if(father instanceof Son1){ //向下转型:子类的引用指向父类的引用 Son1 son1 = (Son1)father; //son1.test(); son1.son1Method(); } }
(父类的引用无法调用子类里独有的方法,必须使用向下转型成对应的子类,才能通过子类去调用子类中独有的方法在向下转型的时候,容易出现ClassCastException(类型转换异常),原因是将父类引用转换成了不匹配的子类对象可以通过instanceof关键字类判断父类引用指向的是哪一个子类实例,从而避免类型转换异常)