一、封装
封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。
对于封装而言,一个对象它所封装的是自己的属性和方法,所以它是不需要依赖其他对象就可以完成自己的操作。
1、封装的步骤:
· 使用private 关键字来修饰成员变量
· 对需要访问的成员变量,提供对应的一对getXxx 方法和setXxx 方法。
2、private的含义
· private 是一个权限修饰符,代表最小权限。
· 可以修饰成员变量 和成员方法 。
· 被private 修饰后的成员变量和成员方法,只在本类中才能访问。
3、使用封装的优点
(1)良好的封装能够减少耦合。
(2)类内部的结构可以自由修改。
(3)可以对成员进行更精确的控制。
(4)隐藏信息,实现细节。
一般情况下封装实现如下:
private String name;
private int age;
public void setName(String n){
name=n;
}
public void setAge(int a){
age=a;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
如果出现参数变量与成员变量同名的话,setXxx()函数就赋值不了,所以我们要对setXxx()函数要做出以下改变,getXxx函数不变。
封装优化–this关键字(this代表所在类的当前对象的引用(地址值),即对象自己的引用。)
private String name;
private int age;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
封装优化–构造方法(当一个对象被创建时候,构造方法用来初始化该对象,对象的成员变量赋初值)
private String name;
private int age;
public Student(){///无参构造方法
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
二、继承
多个类中存在相同属性和行为时,将这些内容抽取到一个单独的一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。
1、什么是继承?(所有类默认继承Object,作为父类)
就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
·继承的特点: Java只支持单继承,不支持多继承。
·运用继承的优点: 提高代码的复用性;类与类之间产生了关系,是多态的前提。
·继承的格式:
class 父类{
...
}
class 子类 extends 父类{
...
}
2、继承后的特点:
(1)成员变量
1)成员变量不重名:子类父类中没有出现重名的成员变量,访问不影响。
class fu{
int num = 5;
}
class zi extends fu{
int num1 = 6;
public void show(){
System.out.println(num);
System.out.println(num1);
}
}
///测试类
zi z = new zi();
z.show();///输出5 6
2)成员变量重名:子类父类中出现重名的成员变量,访问受影响。输出按照就近原则。
class fu{
int num = 5;
}
class zi extends fu{
int num = 6;
public void show(){
System.out.println(num);
System.out.println(num);
}
}
///测试类
zi z = new zi();
z.show();///输出6 6
fu类的成员变量是非私有的,子类可以直接访问;否则,就不可以直接访问。
(2)成员方法
1)成员方法不重名,没有影响。
class fu{
public void show(){
System.our.println("fu类中的show方法执行");
}
}
class zi extends fu{
public void show1(){
System.out.println("zi 类中的show1方法执行");
}
}
///测试类
zi z = new zi();
z.show();
z.show1();
(2)成员方法重名–重写(返回值、方法名、参数列表都相同的覆盖效果),按照就近原则(只执行子类的方法)
注意:子类方法覆盖父类方法,必须要保证权限大于等于父类权限;子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
(3)构造方法(构造器)
构造器的特点:
· 构造器与类同名
· 每个类可以有一个以上的构造器
· 构造器可以有0、1、或多个参数
· 构造器没有返回值
· 构造器总是伴随着new操作一起调用
1)构造方法的名字是与类名一致的。所以无法继承父类构造方法的。
2)构造方法的作用是初始化成员变量的,所以子类的初始化过程中,必须先执行初始化动作。子类的构造方法默认有一个super(),表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。
class fu{
fu(){///父类构造方法
System.out.println("fu()!!!");
}
}
class zi extends fu{
super();///调用父类的构造方法
System.out.println("zi()!!!");
}
三、多态
1、什么是多态?
多态就是指通过不同的事物,可以体现出来的不同的形态。(如:动物:狗、猫、猪…。酒:五粮酒、江南春、酒鬼酒)
· 使用多态的前提:
(1)继承或实现
(2)方法的重写(重写:方法名、以及参数列表都一样)
(3)父类引用指向子类对象(向上转型)
· 多态定义的格式:
父类类型 变量名 = new 子类对象;
变量名.方法名;
fu f = new zi();
f.method();
注意:当使用多态方式调用多态时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后的方法。
2、多态的转型
多态的转型:向上转型和向下转型。
(1)向上转型: 多态本身是子类类型向父类型向上转换的过程,这个过程是默认的。
(2)向下转型: 父类类型向子类类型向下转换的过程,这个过程是强制的。
子类类型 变量名 = (子类类型) 父类变量名
Animal a = new Cat();///向上转换
Cat c = (Cat) a;///向下转换
为什么添加了向下转型?
多态本身不能调用子类拥有的方法,而父类没有的方法。所以想要调用子类特有的方法,必须做向下转型。
3、多态的实现方式
(1)基于继承实现的多态
基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。
package lianxi;
class Animal{
public void eat(){
System.out.println("eat!!!");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("cat吃鱼");
}
public void catskill(){
System.out.println("cat会抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("dog吃骨头");
}
public void dogskill(){
System.out.println("dog会看家");
}
}
public class test {
public static void main(String [] args){
Animal a = new Cat();///向上转型
a.eat();
Cat cat = (Cat) a;///向下转型
cat.catskill();
}
}
上面的代码只是打印Cat的技能而已,如果我们还想打印Dog的技能,我们可能会想到直接加:
Dog dog = (Dog) a;///a已经创建为Cat类型了
dog.dogskill();
不就行了吗,这会导致编译错误的,运行抛出ClassCastException,类型转换异常!这是因为明明创建了Cat类型对象,,运行是当然不能转换成Dog对象的。但是Java中提供了一个instanceof关键字,给引用类型的校验,格式如下:
变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false。
把上面的代码改一下的核心代码:
Animal a = new Cat();///向上转型
a.eat();
if(a instanceof Cat){
Cat cat = (Cat) a;///向下转型
cat.catskill();
}
else if(a instanceof Dog){///如果a类型为Dog()类型的话
Dog dog = (Dog) a;
dog.dogskill();
}
(2)基于接口实现的多态
在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。
参考黑马程序员的资料,定义USB接口,实现笔记本类,鼠标类,键盘类:
package lianxi;
import java.security.Key;
interface USB{
void open();///开启功能
void close();///关闭功能
}
class Mouse implements USB{///鼠标类
public void open(){
System.out.println("鼠标开启,红灯亮起来!");
}
public void close(){
System.out.println("鼠标关闭,红灯熄灭!");
}
public void click(){///鼠标特有功能,父类没有,子类拥有
System.out.println("鼠标单击!");
}
}
class KeyBoard implements USB{///键盘类
public void open(){
System.out.println("键盘开启,橙灯亮起!");
}
public void close(){
System.out.println("键盘关闭,橙灯熄灭!");
}
public void type(){///键盘特有的功能
System.out.println("键盘打字!");
}
}
class Laptop{///笔记本类
public void run(){
System.out.println("笔记本运行");
}
public void useUSB(USB usb){
if(usb!=null){
usb.open();
if(usb instanceof Mouse){
Mouse mouse = (Mouse) usb;
mouse.click();
}else if(usb instanceof KeyBoard){
KeyBoard keyBoard = (KeyBoard) usb;
keyBoard.type();
}
usb.close();
}
}
public void shutDown(){
System.out.println("笔记本关闭");
}
}
public class test {
public static void main(String [] args) {
Laptop it = new Laptop();
it.run();///笔记本运行
USB usb = new Mouse();
it.useUSB(usb);///使用鼠标
KeyBoard keyBoard = new KeyBoard();
it.useUSB(keyBoard);
it.shutDown();///笔记本关闭
}
}
/*
笔记本运行
鼠标开启,红灯亮起来!
鼠标单击!
鼠标关闭,红灯熄灭!
键盘开启,橙灯亮起!
键盘打字!
键盘关闭,橙灯熄灭!
笔记本关闭
*/
四、参考资料
1、黑马程序员的PDF资料
2、https://www.cnblogs.com/chenssy/p/3372798.html
3、