封装
什么是封装?
隐藏实现细节,暴露出合适的访问方式(合理隐藏,合理暴露)
封装的实现步骤
1、一般对类的成员变量使用private(私有)关键字进行修饰隐藏,用private关键字修饰过的变量,只能在当前类中访问
2、提供public修饰的公开的getter和setter方法暴露其取值和赋值
package com.osskey.fengzhuang;public class Demo {public static void main(String[] args) {Student s = new Student();s.setAge(20);//s.getAge();System.out.println("这个学生的年龄是:"+s.getAge());}}
package com.osskey.fengzhuang;public class Student {private int age;private String name;private String sex;public void setAge(int age){if (age>0 && age<100){this.age = age;}else {System.out.println("输入错误!");}}public int getAge(){return age;}}

JavaBean
JavaBean可以理解为一个实体类,他的对象可以用于在程序中封装数据
标准JavaBean需要满足的条件
1、成员变量需要用private修饰
2、提供每一个成员变量对应的setXXX()和getXXX()方法
3、必须提供一个无参构造器
继承
什么是继承?
继承是类与类之间的一种关系。子类(派生类)可以继承父类(基类,超类)的属性和方法。
继承关系在JAVA代码中如下:
public class Students extends People{} //学生类继承人类的属性和方法
继承的特点
- 子类可以继承父类的属性和方法,但是不能继承父类的构造器
- Java是单继承模式,一个类只能继承一个父类
- Java不支持多继承,但是支持多层继承
- Java中所有的类都是Object类的子类
一些疑问:
- 子类知否可以继承父类的构造器?
不可以,子类有自己的构造器,父类的构造器用于初始化父类对象
- 子类是否可以继承父类的私有成员变量?
其实是可以的,但是只是继承,不能直接访问,不能用
继承后:成员访问的原则
- 在子类方法中访问成员变量(成员方法,成员变量)满足:就近原则
(1)先在子类局部范围(比如子类中的方法)中寻找要使用的成员变量
(2)然后再子类成员范围中寻找
(3)最后在父类成员范围中寻找,如果没有找到就报错
- 如果在子类中出现了重名的成员(比如:父类和子类都出现了name变量),会优先使用子类的成员,如果一定要使用父类的成员则可以使用super关键字,指定访问父类的成员。
格式:super.父类成员变量/成员方法
package com.osskey.extendsdemo;public class superdemo {public static void main(String[] args) {dog dog = new dog();dog.run();System.out.println("-----------");dog.go();}}class Aminal{public String name="这是动物类";public void run1(){System.out.println("动物类是父类");}}class dog extends Aminal{public String name;public void run(){System.out.println(super.name);}public void run1(){System.out.println("狗类是子类");}public void go(){run1();super.run1();}}
继承后:方法重写
什么是方法重写?
在继承体系中,子类出现了和父类一模一样的方法声明,就称子类的这个方法是重写的方法
如果父类里的某个方法,只能提供一部分子类的需求,但是又不能满足全部子类的需求,这时就可以利用方法重写,用super继承一部分父类方法,再加上增加的功能,组成一个新的成员方法
Override重写注释
@Override 放在重写后的方法上,作为重写是否正确的校验注解
加上该注解后,如果重写错误,编译阶段会出现错误提示
方法重写的注意事项
- 私有方法不能被重写
- 重写方法的名称,形参列表必须和被重写的方法保持一致
- 子类重写父类方式时,访问权限必须大于或等于父类(缺省<protected<public)
- 子类不能重写父类的静态方法 (为什么?方法重写的前提是首先要继承父类的被重写方法,而静态方法是不存在继承关系的,它是一种共享的方法,所以静态方法不能重写)
继承后:子类构造器的特点
子类中的所有构造器都会默认先访问父类中的无参构造器
子类构造器默认第一行是super(),不写也是默认存在的
继承后:子类访问父类有参构造器
如果父类只有有参构造器,没有无参构造器,那么子类内的构造器也必须是有参构造器,且用super()传递构造器的变量。具体声明如下:
package com.osskey.extendsdemo;public class People {private String name;private int age;//只有有参构造器,没有无参构造器public People(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
package com.osskey.extendsdemo;public class Strudent extends People {//父类中没有无参构造器,子类也必须是有参构造器public Strudent(String name, int age) {/*通过super()传递参数到父类中去*/super(name, age);}}
对上面这个代码做了一些完善
package com.osskey.extendsdemo;public class People {private String name;private int age;public People(String name, int age) {this.name = name;this.age = age;}public People() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
package com.osskey.extendsdemo;public class Strudent extends People {private String className;//有参构造器赋值,即对父类的有参构造器赋值,也对子类内的className变量赋值public Strudent(String name, int age,String className) {super(name, age);this.className = className;}public Strudent() {}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}}
package com.osskey.extendsdemo;public class testdemo {public static void main(String[] args) {Strudent stu = new Strudent("张三",18,"一班");System.out.println(stu.getName());System.out.println(stu.getAge());System.out.println(stu.getClassName());}}

this和super

this()访问兄弟构造器(本类构造器)

如果用户有输入name和schoolName参数,则使用用户输入的;如果用户没有输入schollName参数,则通过无参构造器中的this(),将默认指定的值传递给有参构造器
this()和super()使用注意

多态
什么是多态?

package com.key.d13_packeg_01.duotaidemo;public abstract class Aminal {public String name = "父类动物";public abstract void run();}
package com.key.d13_packeg_01.duotaidemo;public class dog extends Aminal{public String name = "子类动物";@Overridepublic void run() {System.out.println("狗跑的很快");}}
package com.key.d13_packeg_01.duotaidemo;public class cat extends Aminal{@Overridepublic void run() {System.out.println("猫跑的很慢");}}
package com.key.d13_packeg_01.duotaidemo;public class polymorphic {public static void main(String[] args) {//1、多态的形式:父类类型 对象名称 = new 子类构造器Aminal a1 = new dog();/*** 多态的方法调用:编译看左边,运行看右边*/a1.run();/*** 多态的变量调用:编译看左边,赋值还看左边*/System.out.println(a1.name);Aminal a2 = new cat();a2.run();}}package com.key.d13_packeg_01.duotaidemo;public class polymorphic {public static void main(String[] args) {//1、多态的形式:父类类型 对象名称 = new 子类构造器Aminal a1 = new dog();a1.run();Aminal a2 = new cat();a2.run();}}

使用多态的前提

多态的优势

多态下引用数据类型的类型转换

package com.key.d13_packeg_01.duotaidemo;public class tiger extends Aminal{@Overridepublic void run() {System.out.println("老虎跑得很快");}public void eat(){System.out.println("老虎吃肉");}}
package com.key.d13_packeg_01.duotaidemo;public abstract class Aminal {public String name = "父类动物";public abstract void run();}
package com.key.d13_packeg_01.duotaidemo;public class changemethod {public static void main(String[] args) {Aminal t = new tiger();//t.eat();//这里Amial类对象t无法调用eat()方法,因为eat()方法是子类tiger独有的方法,父类Aminal中没有eat()方法/*** 将Aminal类型的t强制转换为tiger类型的t1*/tiger t1 = (tiger) t; //从父类类型到子类类型必须强制转换t1.eat();}}

注意的地方

package com.key.d13_packeg_01.duotaidemo;public class changemethod {public static void main(String[] args) {Aminal t = new tiger();//t.eat();/*** 将Aminal类型的t强制转换为tiger类型的t1*/tiger t1 = (tiger) t; //从父类类型到子类类型必须强制转换t1.eat();/*** 通过instanceof判断对象类型后再进行强制类型转换*/Aminal t2 = new tiger();if (t2 instanceof tiger){tiger t3 = (tiger) t2;t3.eat();}else if (t2 instanceof dog) {dog d = new dog();d.run();}}}

多态实际应用编程

USB接口,实现类Mouse,实现类Keyboard,类Computer,测试类test
package com.key.d13_packeg_01.duotaidemo.ceshianli;public interface USB {void in();void out();}
package com.key.d13_packeg_01.duotaidemo.ceshianli;public class Mouse implements USB{private String name;public Mouse(String name) {this.name = name;}@Overridepublic void in() {System.out.println("接入" + name + "鼠标。。。");}@Overridepublic void out() {System.out.println("拔出" + name + "鼠标。。。");}public void click(){System.out.println("点击" + name + "鼠标。。。");}public String getName() {return name;}public void setName(String name) {this.name = name;}}
package com.key.d13_packeg_01.duotaidemo.ceshianli;public class Keyboard implements USB{private String name;public Keyboard(String name) {this.name = name;}@Overridepublic void in() {System.out.println("接入" + name + "键盘。。。");}@Overridepublic void out() {System.out.println("拔出" + name + "键盘。。。");}public void type(){System.out.println("使用"+ name +"键盘打字。。。");}public String getName() {return name;}public void setName(String name) {this.name = name;}}
package com.key.d13_packeg_01.duotaidemo.ceshianli;public class Computer {private String name;public Computer() {}public Computer(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}/*** 提供安装USB设备的入口*/public void installUSB(USB usb){usb.in();/*** 调用独有方法*/if (usb instanceof Mouse){Mouse mouse = (Mouse) usb;System.out.println("此usb设备是" + mouse.getName() + "鼠标");//usb.in();mouse.click();//usb.out();}else if (usb instanceof Keyboard){Keyboard keyboard = (Keyboard) usb;System.out.println("此usb设备是" + keyboard.getName() + "键盘");//usb.in();keyboard.type();//usb.out();}else {System.out.println("安装失败!");}usb.out();}}
package com.key.d13_packeg_01.duotaidemo.ceshianli;public class test {public static void main(String[] args) {//创建电脑对象Computer computer = new Computer("Mac Book Pro");USB mouse = new Mouse("雷蛇");USB keyboard = new Keyboard("樱桃");System.out.println("======" + computer.getName() + "======");computer.installUSB(mouse);System.out.println("==========");computer.installUSB(keyboard);System.out.println("==========");}}

