1.方法重写
子类重现(重新定义)了超类定义的方法 超类:不仅仅指的是父类,也可能是爷爷类(其实就是祖先类)
1.1、Object类
所有类都有一个共同的超类:Object
Object类是所有类的父类
Object类被子类经常重写的方法:
super
仅表示父类,不能表示父类的父类,或者更早的类
1.2、重写的使用语法规则:
- 方法名相同
- 参数列表相同
- 返回值类型相同或者是其子类
- 子类访问权限(访问修饰符)不能严于父类(不能小于父类的访问修饰符)
- 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
- 子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
- 父类的私有方法不能被子类覆盖
- 不能抛出比父类方法更多的异常
方法重写与方法重载的区别:
代码案例:
/*
描述一个人的类
名字 是私有的,提供了set 和 get,这是封装技术的体现
行为:说
*/
public class Person {
private String name; // 引用数据类型的默认值:null
public Person() {
}
public Person(String name) { // 构造重载一次
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say(){
System.out.println(name+"说:你好,世界");
}
}
public class Teacher extends Person{
private boolean flag; // 基本数据类型,默认值是false
public Teacher(String name) {
super(name); // 引用super来使用父类构造
}
public Teacher(String name, boolean flag) {
super(name);
this.flag = flag;
}
// 方法重写
@Override
public void say() {
if (flag){
System.out.println("我考过教师资格证。");
}else {
System.out.println("我没考过教师资格证");
}
super.say();
}
}
// 继承Person 不会处处哦,为什么继承Teacher会出错?
// 因为Teacher没有默认无参构造方法
public class ItTeacher extends Teacher{
private String zhuanye;
// 一个类继承一个类时,默认会使用超类的无参构造
public ItTeacher(String name) {
//super(name); // 超类一个参数的构造
this(name,false); // 调用第二个构造
}
public ItTeacher(String name, boolean flag) {
//super(name, flag); // 超类,两个参数的构造
this(name,flag,""); // 调用第三个构造
}
public ItTeacher(String name, boolean flag, String zhuanye) {
super(name, flag); // 调用超类构造
this.zhuanye = zhuanye;
}
@Override
public void say() {
super.say();
System.out.println(super.getName()+"教授的课程是:"+zhuanye);
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setName("张三"); // 使用封装提供的set设置或者修改name
person.say(); //
System.out.println("案例一----------------");
Person person1 = new Person("李四");
person1.say();
System.out.println("案例二----------------");
Teacher teacher = new Teacher("五五");
teacher.say();
System.out.println("案例三-------");
Teacher teacher1 = new Teacher("赵六", true);
teacher1.say();
System.out.println("案例四---------------");
ITTeacher itTeacher = new ITTeacher("易建联", true, "大数据");
itTeacher.say();
}
}
2.泛化 多态
泛化:子类型转为超类型的现象
泛化带来的好处(目的):统一控制 往上转型
多态:泛化后统一控制时,由子类型自动决定执行的行为 父类的引用指向子类的对象
多态:同一个引用类型,使用不同的实例而执行不同操作
代码案例:
public class BMO extends Che{
/*private String che;
public String getChe() {
return che;
}
public void setChe(String che) {
this.che = che;
}*/
public BMO(String xxx) {
//this.che = xxx;
super(xxx);
}
// 方法重写
@Override
public void run(){
System.out.println("像风一样来了。。。");
}
// Test2测试的例子
@Override
public String toString() {
return super.toString()+getName();
}
}
public class AoTuo extends Che{
/*private String che;
public String getChe() {
return che;
}
public void setChe(String che) {
this.che = che;
}*/
public AoTuo(String che) {
//this.che = che;
super(che);
}
@Override
public void run(){
System.out.println("二手车来了。。。。");
}
}
public class YaDi extends Che{
/*private String che;
public String getChe() {
return che;
}
public void setChe(String che) {
this.che = che;
}*/
public YaDi(String che) {
super(che);
}
@Override
public void run() {
System.out.println("电动车来了。。。。。。");
}
}
public class Che {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Che(String name) {
this.name = name;
}
public void run(){
System.out.println("我不知道怎么运行。。。。。。");
}
}
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student() {
}
public Student(String name) {
this.name = name;
}
/*public void driver(BMO bmo) {
System.out.println(name+"正在驾驶宝马"+bmo.getChe());
}
public void driver(AoTuo aoTuo){
System.out.println(name+"正在驾驶宝马"+aoTuo.getChe());
}*/
/*public void driver(YaDi che){
System.out.println(name+"正在驾驶"+che.getName()+"来了");
che.run(); //
}*/
public void driver(Che che) {
System.out.println(name+"正在驾驶"+che.getName()+"来了");
che.run(); // 多态
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student("张三");
//BMO bmo = new BMO("x6");
//AoTuo aoTuo = new AoTuo("奥托");
//YaDi yaDi = new YaDi("雅迪003");
Che che = new YaDi("x5"); // 此处是泛化现象,父类的引用指向子类的对象
//Che che = new Che("小汽车");
student.driver(che);
}
}
public class Test2 {
public static void main(String[] args) {
System.out.println("hello world");
Object obj = new BMO("宝马"); // 泛化
System.out.println(obj); // 泛化是任何对象都泛化为Object 多态调用 toString方法
}
}
泛化多态的前提是:需要有is-a(继承)关系 或者 is-like(接口实现)关系
注意:
转型:1.往上转型 2.往下转型
往下转型:是安全的,自动的
<父类型> <引用变量名> = new <子类型>();
此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法
此时通过父类引用变量无法调用子类特有的方法
往下转型:要手动强制转型 是不安全的现象
<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;
在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常
转型案例练习:
往下转型,类转错,报错为:ClassCastException:
public class Test {
public static void main(String[] args) {
Super1 super1 = new Sub1(); // 泛化,往上转型
Super1 super11 = new Sub2(); // 泛化,往上转型
Sub1 sub1 = (Sub1) super1; // 往下转型,手动强制转换,存在风险
//Sub1 sub11 = (Sub1) super11; // error 不能将Sub2转换为Sub1 报错为:ClassCastException:
}
}
class Super1{
}
class Sub1 extends Super1{
}
class Sub2 extends Super1{
}
1.构造方法的执行流程:?
public class Test2 {
public static void main(String[] args) {
// 构造方法执行顺序
new D(); // 本质上,创建了4个对象 Object A B C
// 对象的创建,执行了构造
}
}
class A{
public A(){
// super 始终在构造方法中的第一行
super(); // 默认:Object
System.out.println("a.........");
}
}
class B extends A{
public B(){
super(); // 默认:A构造
System.out.println("b.......");
}
}
class C extends B{
public C(){
super(); // 默认:B构造
System.out.println("c.......");
}
}
class D extends C{
public D(){
super();
System.out.println("d....");
}
}
2.初始化块:?
初始化块存在{}
里面,没有任何关键字修饰
初始化块:优先于构造方法的顺序,但不优先于父类,也就是优先于本部
public class Test {
public static void main(String[] args) {
new A(12);
}
}
class Super{
public Super(){
System.out.println("super......");
}
}
class A extends Super{
public A(){
System.out.println("无参构造");
}
public A(int i){
//System.out.println("初始化块。。。");
System.out.println("i = "+i);
}
public A(String s){
System.out.println("s = "+s);
}
// 类中只能编写定义语句,第一字段 成员 方法 内部类 块
// 初始化块:优先于构造方法的顺序,但不优先于父类,也就是优先于本部
{
System.out.println("初始化块");
}
}
3.子类继承父类时什么是可以继承的?什么是不可以继承的?
子类能访问的父类任何东西,表示继承成功
被private修饰的不能被继承
被public修饰的一定能继承
构造方法不能被继承
xx.xx 这叫调用,super() this()这不叫调用
public class Test3 {
// 如何证明有没有继承呢? 子类能访问的父类任何东西,表示继承成功
}
// xx.xx 这叫调用,super() this()这不叫调用
class S1{
public int i;
int n;
protected int k;
private int j;
// 内部类
class S2 extends S1{
void foo(){
// this 表示S2
// S1.this 表示S1
System.out.println(S1.this.j);
System.out.println(this.i);
}
}
}
class S2 extends S1{
void foo(){
System.out.println(this.i);
}
}
异常:再讲方法重写