JavaSE(10) - 面向对象进阶
P129 认识多态 (polymorphism)
- 多态就是对象的多种形态
- 多态的前提是: 1,有继承/实现关系 2,有父类引用指向子类对象 3,有方法重写
- 多态的好处: 使用父类型作为参数, 可以接收所有子类对象,体现多态的扩展性与便利
P130 多态调用成员的特点
- 调用成员变量 : 编译看左边, 运行也看左边
- 调用成员方法 : 编译看左边, 运行看右边
P131 多态的优势和弊端
1, 多态的优势
方法中, 使用父类型作为参数, 可以接收所有子类对象
2, 多态的弊端
不能使用子类的特有功能,如果要用要转换回子类对象
3, 引用数据类型的类型转换有两种, 自动类型转换, 强制类型转换
Person p = new Student();//自动类型转换,小变大
Student s = (Student)p;//强制类型转换,大变小
4, 强制类型转换可以转换成真正的子类类型, 从而调用子类独有功能
转换类型与真实类型不一致会报错,这时可以用instanceof关键字进行判断
//判断变量a是不是Dog类型,如果是就返回true,否则返回false,
if(a instanceof Dog){
Dog d = (Dog)a;
d.lookHome();
}else if(a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse();
}else{
System.out.println("没有这个类型,无法转换.");
}
P132 多态的综合练习
根据需求完成代码:
- 定义狗类
属性:
年龄,颜色
行为:
eat(String something)(someth丨ng表示吃的东西)
看家lookHome方法(无参数)
- 定义猫类
属性:
年龄,颜色
行为:
eat(String something)方法(something表示吃的东西)
逮老鼠ScatchMouse方法(无参数)
- 定义Person类//饲荞员
属性:
姓名,年龄
行为:
keepPet(Dog dog,String something)方法
功能:隈养宠物狗,something表示喂荞的东西
行为:
keepPet(Cat cat,String something)方法
功能:喂荞茏物猫,something表示喂养的东西 生成空参有参构造,set和get方法
- 定义测试类(芫成以下打印效果):
keepPet(Dog dog,String somethind)方法打印内容如下:
年龄为30岁的老王养了一只黑颜色的2岁的狗 2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃
keepPet(Cat cat,String someth丨nd)方法打印内容如下:
年龄为25岁的老李养了一只灰颜色的3岁的猫 3岁的灰顔色的猫,眯着眼睛侧着头吃鱼
- 思考:
1 .Dog和Cat都是Animal的子类,以上案例中针对不同的动物,定义了不同的keepPet方法,过于繁琐, 能否简化,并体会简化后的好处?
2.Dog和Cat虽然都是Animal的子类,但是都有其特有方法,能否想办法在keepPet中调用特有方法?
P133 包和final
包就是文件夹. 用来管理各种不同功能的Java类, 方便后期代码的维护.
包名的规则: 公司域名反写 + 包的作用, 需要全部英文小写, 见名知意. com.itheima.domain.Student
导包, 使用其它类的规则
-
使用同一个包中的类时, 不需要导包
-
使用java.lang包中的类时, 不需要导包
-
其它情况都需要导包
-
如果同时使用两个包中的同名类, 需要用全类名.
-
全类名 = 包名 + 类名
final 关键字
可以修饰 方法, 类, 变量.
- final修饰方法 : 表明该方法时最终方法, 不能被重写.
- final修饰类 : 表明该类是最终类, 不能被继承.
- final修饰变量 : 叫做常量, 只能被赋值一次.
常量
实际开发中, 常量一般作为系统的配置信息, 方便维护, 提高可读性.
常量的命名规范:
- 单个单词 : 全部大写
- 多个单词 : 全部大写, 单词之间用下划线隔开.
细节 :
- final修饰的变量是基本类型 : 那么变量存储的数据值不能改变
- final修饰的变量是引用类型 : 那么变量存储的地址值不能发生改变, 对象内部的可以改变.
- 核心 : 常量记录的数据是不能改变的.
大小写转换 快捷键 CTRL + shift +U
P134 权限修饰符和代码块
- private 只能本类用
- 默认 只能本包用
- protected 受保护的 , 不同包下的子类可以用
- public 公共的 , 不同包下的子类/无关类都可以用
在实际开发中, 一般只用private和public
- 成员变量私有
- 方法公开
特例 : 如果方法中的代码是抽取其它方法中共性代码, 这个方法一般也私有.
代码块
一,局部代码块
二,构造代码块(已经不用了)
- 写在成员位置的代码块
- 作用 : 可以把多个构造方法中重复的代码抽取出来
- 执行时机 : 我们在创建本类对象的时候会先执行构造代码块在执行构造方法
三,静态代码块
格式 : static{}
执行时机 : 随着类的加载而加载 , 并且只执行一次.
应用场景 : 可以在程序开始时, 做一些数据初始化工作. 比如,在学生管理系统中事先添加一些用户信息, 以便用户登录.
P135 抽象类和抽象方法
-
抽象类的作用
抽取共性时, 无法确定方法体, 就把方法定义为抽象的.
强制让子类按照某种格式重写.
抽象方法所在的类, 必须是抽象类
-
抽象类和抽象方法的格式
public abstract 返回值类型 方法名 (参数列表)
public abstract class 类名{}
-
继承抽象类要注意的
要么重写抽象类中的所有抽象方法
要么是抽象类
练习:
青蛙 frog 属性: name ,age 吃虫子,喝水
狗 dog ... 吃骨头,喝水
山羊 sheep ... 吃草 ,喝水
P 136 接口
接口的定义和使用
-
接口用关键字interface来定义 public interface 接口名{}
-
接口不能实例化
-
接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名{}
-
接口的子类(实现类)
要么重写接口中的所有抽象方法
要么是抽象类
注意1 : 接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名 1 ,接口名2 {}
注意2 : 实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类 implements 接口名 1 ,接口名2 {}
练习:
编写带有接口和抽象类的标准Javabean类
青蛙 名字,年龄 行为:吃虫子, 游泳
狗 ... 吃骨头, 狗刨
兔子 ... 吃胡萝卜
P137 接口的特点: 成员特点和各种关系
-
成员变量
只能是常量
默认修饰符 : public static final
-
构造方法
没有
-
成员方法
只能是抽象方法
默认修饰符 : public abstract
-
JDK7以前 : 接口中只能定义抽象方法.
接口和类之间的关系
- 类和类的关系
继承关系,只能单继承,不能多继承,但是可以多层继承
- 类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口的关系
继承关系,可以单继承,也可以多继承
P138 接口和抽象类综合案例
乒乓球运动员:姓名,年龄,学打乒乓球,说英语
篮球运动员:姓名,年龄,学打篮球
乒乓球教练:姓名,年龄,教打乒乓球,说英语
篮球教练: 姓名,年龄,教打篮球
sporter(运动员) coach(教练员)
P139 多学3招
JDK8以后接口中新增的方法, 有方法体的方法
- 允许在接口中定义默认方法,需要使用关键字default修饰
作用:解决接口升级的问题
接口中默认方法的定义格式:
-
格式:public default 返回值类型方法名(参数列表)
-
范例:public default void show()
接口中默认方法的注意事项:
-
默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
-
public可以省略,default不能省略
-
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
JDK8以后接口中新增的方法,静态方法
-
允许在接口中定义定义静态方法,需要用static修饰
接口中静态方法的定义格式:
-
格式:public static返回值类型方法名(参数列表)
-
范例:public static void show()
接口中静态方法的注意事项:
- 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用-
- public可以省略,static不能省略
接口的应用
-
接口代表规则,是行为的抽象。想要让哪个类拥有一 个行为,就让这个类实现对应的接口就可以了。
-
当一个方法的参数是接口时,可以传递接口所有实现 类的对象,这种方式称之为接口多态。
适配器设计模式(Design pattern)
简单理解 : 设计模式就是解决问题的套路.
适配器设计模式 : 解决接口与接口实现类之间的矛盾问题.
-
当一个接口中抽象方法过多,但是我只要使用其中一部分的 时候,就可以适配器设计模式
-
书写步骤:编写中间类XXXAdapter,实现对应的接口
对接口中的抽象方法进行空实现
让真正的实现类继承中间类,并重写需要用的方法
为了免其他类创建适配器类的对象,中间的适配器类
用abstract进行修饰
P140 初识内部类
- 什么是内部类?
写在一个类里面的类就叫做内部类
- 什么时候用到内部类?
B类表示的事物是A类的一部分,且B单独存在没有意义。 比如:汽车的发动 机,ArrayUst的迭代器,人的心脏等等
P141 成员内部类
成员内部类如何书写
- 写在成员位置的, 属于外部类的成员.
- 可以被一些修饰符所修饰, 比如 : private , 默认, protected , public ,static等
如何创建成员内部类的对象
方式1 : 在外部类中编写方法, 对外提供内部类的对象.
//在外部类中编写getInstance方法获取内部类对象
Inner getInstance(){
return new Inner();
}
//创建外部类对象,调用方法
Outer o = new Outer();
//如果内部类是私有的,就用父类去接收(多态)
Object inner = o.getInstance();
//或者直接输出
o.getInstance().sout
//如果不想CTRL+alt+v用变量接收而直接打印,就在后边 " .sout"就可以.
方式2 : 直接创建, 格式: 外部类名 . 内部类名 对象名 = 外部类对象 . 内部类对象;
//格式: 外部类名 . 内部类名 对象名 = 外部类对象 . 内部类对象;
Outer.Inner oi = new Outer().new Inner();
小建议 : 给变量起名字时不要去用$和_, $是给内部类使用的, _是给常量使用的.
在File菜单中的Project Structure中选Project可以选择编译的JDK版本.
思考题: 分别输出不同位置的a
public class Outer {
//外部类成员
private int a = 10;
class Inner{
//内部类成员
private int a = 20;
void method(){
//内部类方法中,局部变量
int a = 30;
System.out.println(a);//30
System.out.println(this.a);//20
//Outer.this就是获取了外部类的地址值
System.out.println(Outer.this.a);//10
}
}
}
///////////////////////////////
public class test {
public static void main(String[] args) {
//创建内部类对象
Outer.Inner oi = new Outer().new Inner();
//调用方法
oi.method();
}
}
在程序运行加载到内存时, 内部类和外部类分别加载为两个字节码文件: Outer.class和Outer$Inner.class.
获取外部类的地址值 : 外部类名. this. 例如:Outer.this.a就能调用外部类的成员变量a了.
P142 静态内部类和局部内部类
- 什么是静态内部类?
静态内部类是一种特殊的成员内部类。(用static修饰的内部类)
- 直接创建静态内部类对象的方式?
Outer.lnner oi = new Outer.lnner();
- 如何调用静态内部类中的方法?
非静态方法:先创建对象,用对象调用
静态方法:外部类名.内部类名.方法名();
局部内部类
-
将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
-
外界是无法直接使用,需要在方法内部创建对象并使用。
-
该类可以直接问外部类的成员,也可以访问方法内的局部变量。
P143 匿名内部类
- 什么是匿名内部类?
隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置。
- 匿名内部类的格式?
- 格式的细节
包含了继承或实现,方法重写,创建对象。
整体就是一个类的子类对象或者接口的实现类对象
- 使用场景
当方法的参数是接口或者类时,
以接口为例,可以传递这个接口的实现类对象,
如果实现类只要使用一次,就可以用匿名内部类简化代码。
标签:10,Outer,进阶,子类,接口,JavaSE,方法,public,内部 From: https://www.cnblogs.com/lg369/p/17809645.html