面向对象特征:封装、继承、多态(抽象)
1.封装
体现形式—方法、属性私有化,提供公共访问方式来保证可以进行正常取值和赋值,提高数据安全性
package cn.tedu.fengzhuang;
public class FZDemo{
public static void main(String[]args){
//创建对象--具体英雄
Hero h=new Hero();
//给对象属性进行赋值
/*h.name="亚索";
h.level=1;*/
//调用方法来间接给私有化属性进行赋值
h.setBlood(10);
//展示对象属性
//调用方法来间接给私有化属性进行取值
//System.out.println(h.name+","+h.getBlood()+","+h.level);
}
}
//代表英雄的类
class Hero{
//属性
private String name;
private int level;//等级
//private(关键字---私有化)
//私有化信息是不能在外部直接使用的
private int blood;//血量
//快捷键---Alt+InsertGenerator---GetterandSetter
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getLevel(){
return level;
}
public void setLevel(int level){
this.level=level;
}
public int getBlood(){
return blood;
}
public void setBlood(int blood){
this.blood=blood;
}
/*//提供间接给私有属性进行赋值
public void setBlood(int blood){
if(blood<0){
System.out.println("亲,您血量给值有问题!!!");
}else{
this.blood=blood;
}
}
//提供间接获取私有属性值
public int getBlood(){
return blood;
}*/
/*//有参构造来判断血量是否小于0
public Hero(int blood){
if(blood<0){
System.out.println("亲,您血量给值有问题!!!");
}else{
this.blood=blood;
}
}*/
}
2.继承
2.1 概念
当多个类中内容出现了重复,把重复内容放到新的类中,通过extends关键字让原来的类和新的类产生关联关系—继承。原来的类称之为子类/派生类,新的类称之为父类/超类。子类可以获取父类部分信息(子类继承不了父类里私有化信息,构造方法以及构造代码块)。
package cn.tedu.extends x;
public class Extends Demo1{
public static void main(String[]args){
//创建子类对象
Doctor d=new Doctor();
//
d.treat();
}
}
//定义代表医疗人员类
//父类/超类
class 医疗人员{
//属性
String name;
int age;
char gender;
//科室
String dept;
//方法
public void treat(){
System.out.println(name+"在治病救人...");
}
}
//定义代表医生的类
//通过extends关键字让医生类和医疗人员类产生关联关系---继承
//子类/派生类
class Doctor extends 医疗人员{
public void treat(){
System.out.println(name+"拿着手术刀在治病救人...");
}
}
//定义代表护士的类
class Nurse extends 医疗人员{
}
2.2 继承方式(类与类之间支持单继承)
子类只能有一个父类,父类可以有多个子类
A类继承B类,B类继承C类—C类是A类父类(多级继承)
2.3 重写(覆盖)
当父子类中出现方法签名一致的方法 遵守重写原则(两等两小一大)
父子类的方法签名一致
当父类的方法返回值类型是基本数据类型/void,子类的方法返回值类型就和父类一致
Class A{
Public void m(){}
}
Class B extends A{
Public void m(){}
}
当父类方法的返回值类型是引用数据类型,那么子类的方法返回值类型要么和父类方法返回值类型一致要么是父类方法返回值类型的子类
Class A{}
Class B extends A{}
Class C{
Public A m(){return null;}
}
Class D extends C{
Public A/B m(){return null;}
}
访问权限修饰符(根据权限来限定可以在位置关系下访问信息)
位置关系(当前访问信息的地方和信息定义地方共同作用)—本类、同包类、其他类、子类
子类方法访问权限修饰符要么和父类访问权限修饰符一致要么比父类访问权限修饰符范围要大
Class A{
void m(){}
}
Class B extends A{
Public void m(){}
}
2.4 super
a.关键字,代表父类对象可以调用信息
b.super语句—在子类构造方法里调用父类构造,使用时要在首行
c.每个子类构造方法里默认含有super无参语句来调用父类无参构造,当父类没有提供无参构造,子类所有的构造方法需要去手动添加super语句去调用父类对应形式的有参构造
d.保证父类对象优先于子类对象先存在(父子类执行顺序—先执行父类构造代码块、父类构造方法、子类构造代码块、子类构造方法)
package cn.tedu.extends x.b;
public class Extends Demo3{
public static void main(String[] args){
//创建代表猪的类的对象
Pig p=new Pig(1);
//p.eat();
}
}
//代表动物的类
class Animal{
//无参构造
/*public Animal(){
System.out.println("父类无参构造");
}*/
//有参构造
public Animal(int j){
System.out.println("父类有参构造");
}
public void eat(){
System.out.println("在吃东西...");
}
public void sleep(){
System.out.println("在睡觉...");
}
}
//代表猪的类
class Pig extends Animal{
//父类对象优先于子类对象先出现
//无参构造
//子类的所有构造方法里都默认添加super无参语句来调用父类无参构造
public Pig(){
//super语句---在子类构造方法里调用父类构造方法,首行使用
super(1);
System.out.println("子类无参构造");
}
//有参构造
//当父类没有提供无参构造那么子类所有的构造方法需要手动添加super语句
//来调用父类对应形式的有参构造
public Pig(int i){
//
super(2);
System.out.println("子类有参构造");
}
//对eat方法进行重写
public void eat(){
System.out.println("在无忧无虑的吃。。。");
System.out.println("吃饱了。。想睡觉。。。");
//java中所有的非静态信息通过对象来调用
//this?代表的是当前类的对象
//super代表父类的对象,可以调用父类信息
super.sleep();
}
}
3.多态
1.概念
在代码操作过程中呈现的多种形式
从java时期角度来进行分析,体现出多态
编译时多态 在编译时期绑定代码(体现形式—重载)
public void m(){}
public void m(int i){}
运行时多态 在运行时期绑定代码(体现形式–重写-、向上造型 前提都是继承)
2.向上造型
向上造型(对象可以调用那些方法看父类,具体方法执行看子类是否有重写 父类—目录 子类—正文)
package cn.tedu.duotai;
public class DTDemo{
public static void main(String[] args){
//养一个宠物
/*Petp;
//养了一只狗
p=newDog();*/
//当声明类类型是父类,实际创建类类型是子类---向上造型
Pet p=new Dog();
//向上造型对象调用哪个方法看父类
//方法的具体执行看子类是否有重写
p.eat();
//调用方法
//匿名对象---当作参数传递
m (new Pet());
m (new Dog());
m (new Cat());
}
//参数统一调用
public static void m(Petp){//=newPet();=newDog();=newCat();
p.eat();
}
}
//代表宠物的类
class Pet{
public void eat(){
System.out.println("在吃东西....");
}
public void sleep(){
System.out.println("在睡觉...");
}
}
//代表狗的类
class Dog extends Pet{
//重写eat方法
public void eat(){
System.out.println("舔着吃...");
}
public void bark(){
System.out.println("在汪汪汪的叫...");
}
}
//代表猫的类
class Cat extends Pet{
//重写eat方法
public void eat(){
System.out.println("在呼哧呼哧的吃...");
}
public void 磨爪子(){
System.out.println("在悠闲的磨爪子...");
}
}
3.解释重写原则(反证)
1.子类方法访问权限修饰符要么和父类一致要么比父类方法访问权限修饰符范围要大
Class A{
public void m(){}
}
Class B extends A{
void m(){}
}
A a=new B();//向上造型对象a,声明类A类,向上造型对象a可以调用A类m方法,在任意位置都可以调用到m方法。
a.m();//向上造型对象调用方法的具体执行看子类是否有重写,具体调用B类里m方法,在同包范围内可以被调用到。此时前后出现矛盾,证明代码是错的。
2.当父类方法返回值类型是引用数据类型,那么子类方法返回值类型要么和父类方法返回值类型一致要么是父类方法返回值类型的子类
Class A{}
Class B extends A{}
Class C{
Public B m(){return null;}
}
Class D extends C{
Public A m(){return null;}
}
C c=new D();//向上造型的对象c,声明类是C类,调用到C类里m方法返回B类对象,可以调用到B类里信息。
A a=c.m();//方法的具体执行看子类是否有重写,调用的是D类里m方法返回A类的对象,可以调用到A类的信息。此时前后有矛盾,证明代码是错的。
4.优点:
1.统一参数类型
2.解耦(降低耦合度)