一、内容回顾
1、方法重载和方法重写的区别?
1、发生的位置不同,重载是在同一个类中,重写发生在子类里,重写父类中的方法
2、重载是方法名相同、参数不同(个数、类型、顺序)
重写是方法名相同、参数要求相同
3、重载与返回值类型、访问修饰符无关
重写:重写方法的访问修饰符不能比父类中被重写方法更严格
2、什么是多态?如何实现多态?
概念:父类的引用指向子类对象,同一父类类型,对同一行为表现出的不同状态
Human jia=new Worker();
Human zhang=new Student();
jia.eat(); //吃工作餐
zhang.eat(); //吃学生餐
如何实现多态: 父类中编写方法(编写任意方法) 子类中重写父类方法 父类的引用指向子类对象
3、子类继承父类后,创建子类的对象的过程是什么?
先创建最上层的父类对象(Object),依次创建,最后创建子类对象
4、java中的访问修饰符都有哪些?访问权限是什么?
5、什么是继承?子类都继承了父类的哪些成员?
概念:描述类和类之间的一种关系,通过这种关系,子类就可以访问父类中可以访问的成员
public 同包下默认成员 protected
面试题:实现多态有哪些方式?区别是什么?
有两种方式:方法重写 方法重载
区别:
方法重载:静态方式实现多态,在java编译时就已经确定了重载的方法,调用时根据参数决定调用哪个重载
方法重写:动态方式实现多态,在调用时,根据父类的引用指向哪个子类对象,就用哪个子类的方法去覆盖掉父类中的方法
问题:子类何时覆盖掉父类中的方法呢?—在调用时
二、今日内容
1、作业题
2、3个修饰符 static final abstract
3、接口
1、作业题
Q8—1【说明】super和this 不能同时出现在一个构造方法中
当出现this()时,会在this中调用父类构造方法
面向对象3大特征:封装 继承 多态
2、类型转换
自动类型转换:级别低的自动转向级别高
强制类型转换:
向上类型转换:也称为装箱,自动完成,把子类转换为父类类型
向下类型转换:也称为拆箱,强制完成,把父类转换为子类类型
练习:
Pet:属性 name age
方法 eat(){}
Dog:strain
eat(){}
Pet类:
package com.qf.pro2103.day12;
public class Pet {
private String name;
private int age;
public void eat(){
System.out.println("动物在吃");
}
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;
}
}
Dog
package com.qf.pro2103.day12;
public class Dog extends Pet {
private String strain;
public void eat(){
System.out.println("啃骨头");
}
//子类独有方法
public void paly(){
System.out.println(super.getName()+"正在玩接飞盘游戏!");
}
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
}
Cat
package com.qf.pro2103.day12;
public class Cat extends Pet {
private String color;
public void eat(){
System.out.println("吃鱼!");
}
//独有方法
public void getFish(){
System.out.println(super.getName()+"正在钓鱼!");
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
TestPet
package com.qf.pro2103.day12;
public class TestPet {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建多个宠物对象,存放在数组中
//问题:数组的类型是什么---Pet
Pet[] pets=new Pet[5]; //数组的默认值是什么
Dog wangcai=new Dog();
wangcai.setAge(2);
wangcai.setName("旺财");
wangcai.setStrain("拉布拉多");
pets[0]=wangcai;//装箱操作
Cat huanhuan=new Cat();
huanhuan.setColor("白色");
huanhuan.setAge(1);
huanhuan.setName("欢欢");
pets[1]=huanhuan;
Dog dog=new Dog();
dog.setAge(3);
dog.setName("狗宝");
dog.setStrain("京巴");
pets[2]=dog;
//遍历数组
//问题:1、数组中的所有元素都自动装箱了,都转换为父类类型了
// 2、不能调用子类独有方法了
//如果要调用子类独有成员,该怎么办?
//解决:1、先判断是哪种子类类型
// 2、强制转换为子类类型,就可以调用子类独有成员
// instanceof
//语法: 对象名 instanceof 类名
//返回boolean: true---对象是类类型 false---对象不是类类型
// if(pets[1] instanceof Cat){
// Cat tempCat=(Cat)pets[1];
// tempCat.getFish();
// }
//遍历数组:如果是dog,调用play() 是Cat 调用getFish()
for(int i=0; i<pets.length; i++){
//先判断数组是否为null,如果为null则退出循环
if(pets[i]==null){
break;
}else{
//判断是哪种子类类型
if(pets[i] instanceof Dog){
Dog tempDog=(Dog)pets[i];//拆箱操作---把父类转换为子类
tempDog.paly();
}
if(pets[i] instanceof Cat){
Cat tempCat=(Cat)pets[i];
tempCat.getFish();
}
}
}
}
}
面向对象3大特征:封装、继承、多态
面向对象4大特征:抽象、封装、继承、多态
面向对象的设计思路:
1、抽象,发现类
2、发现类的属性
3、发现类的方法
4、优化:封装、继承、多态
3、3个关键之一:abstract
abstract:抽象
问题:当没有方法体时,{}是没有意义的
使用abstract去优化方法
【说明】抽象方法所在的类一定是抽象类,抽象类中不一定有抽象方法。
抽象类不能被new,但是有构造方法
子类继承父类后,如果父类中有抽象方法,那么子类必须要重写(实现)父类中的所有抽象方法
抽象方法的作用:1、无法确定方法体
2、约束子类的作用,子类必须重写(实现)父类的抽象方法,除非子类也具有抽象性
【经验】如果某个类不想被new,那么就可以声明为abstract类,通常父类,用作引用(类型)
4、3个关键字之二:static
static:静态的
能修饰 属性 、方法、 内部类、代码块
【说明】static修饰的成员在程序运行后,就自动加载到内存的方法区中,所以静态成员可以直接访问
访问方式:类名.静态成员名
当程序关闭后,方法区中的static成员才会消失
【经验】各个对象公共的属性、方法 才设置为static
题库系统 答案 使用static
非static修饰的成员,称为实例成员
静态成员和实例成员之间的互相访问
package com.qf.pro2103.day12.statics;
public class Teacher {
public static void main(String[] args) {
// TODO Auto-generated method stub
//在静态方法中可以直接访问静态成员
Teacher.m1();
//在同一类中,静态成员之间互相访问,可以不通过类名,建议通过类名访问
m1();
//在静态方法中不能直接调用实例成员
//Teacher.m2();
Teacher t=new Teacher();
t.m2();
}
//静态方法
public static void m1(){
System.out.println("m1");
}
//实例成员,只有在new后才在堆空间中存在
public void m2(){
System.out.println("m2");
}
}
在实例方法中,是否可以直接访问静态成员?—可以
了解:动态代码块
{}括起来的代码称为动态代码块
执行顺序在属性初始赋值之后,构造方法之前被执行,作用给属性赋值指定初始值
编写.java文件 编译成.class jvm运行.class文件
jvm如何运行的class文件的呢?
加载:懒汉加载—何时使用、何时加载
饿汉加载—程序启动后就被加载
带有静态成员的对象的创建过程
1、父类的静态成员—属性
2、父类的静态成员—代码块
3、子类的静态成员—属性
4、子类的静态成员—代码块
------------------------------------------------------------------以上是静态,以下是实例的
5、父类的实例属性
6、父类的动态代码块
7、父类的构造方法
8、子类的实例属性
9、子类的动态代码块
10、子类的构造方法
总结:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M5J6qe2u-1628762749610)(pics\image-20210810154523031.png)]
4、3个关键字之三 final
最终的
修饰3类成员
修饰属性:常量,值不能被更改
package com.qf.pro2103.day12.finals;
public class Student {
//使用final修饰变量就是常量:不能通过代码改变其值
//常量命名时都使用大写字母
//【说明】属性常量在声明的同时必须赋值
public final String SCHOOL_NAME="千锋大连";
public void test1(){
//SCHOOL_NAME="千锋";//不能改变常量的值
final String CLASS_NAME;
CLASS_NAME="java2103";//局部常量,先声明,然后赋值
System.out.println(CLASS_NAME);
//CLASS_NAME="JAVA2103"; //局部常量赋值后,就不能改变其值。
}
}
修饰方法:最终方法,不能被子类重写
package com.qf.pro2103.day12.finals;
public class Animal {
public final void say(){
System.out.println("你瞅啥?");
}
}
package com.qf.pro2103.day12.finals;
public class Dog extends Animal {
public void say(){ //子类不能重写父类中final修饰的方法
System.out.println("狗在巡视");
}
}
修饰类:最终类,不能被继承
package com.qf.pro2103.day12.finals;
public final class Luozi {
}
package com.qf.pro2103.day12.finals;
public class XiaoLuozi extends Luozi {
}
String 就是final修饰的,不能有子类
总结:
1、类型转换:装箱、拆箱 instanceof
2、abstract
3、static
4、final
作业:1、梳理技能点
2、重做课堂案例
s Dog extends Animal {
public void say(){ //子类不能重写父类中final修饰的方法
System.out.println(“狗在巡视”);
}
}
修饰类:最终类,不能被继承
```java
package com.qf.pro2103.day12.finals;
public final class Luozi {
}
package com.qf.pro2103.day12.finals;
public class XiaoLuozi extends Luozi {
}
String 就是final修饰的,不能有子类
总结:
1、类型转换:装箱、拆箱 instanceof
2、abstract
3、static
4、final
作业:1、梳理技能点
2、重做课堂案例
3、Question8、 9对应的题