java-多态和递归
文章目录
- Day10
- 10.1 this关键字和super关键字区别
- this关键字
- super关键字
- 10.2 当实例化子类时父类做了什么
- 继承案例
- 10.3 多态
- 多态语法格式
- 满足多态的条件:
- 10.4 多态好处
- 10.5 多态中两种类型转换
- 10.6 递归
Day10
10.1 this关键字和super关键字区别
this关键字
- this代表当前这个对象
- this可以访问本类中的实例变量、实例方法、也可以访问本类中的其他构造方法
- this还可以访问父类中的实例变量、实例方法
super关键字
- 表示超类或父类
- super只能在子类中使用,可以访问父类中的实例变量、实例方法 、还可以父类的构造方法
class Person {//构造方法public Person(){}public Person(String name,char sex,int age){this.name = name;this.sex = sex;this.age = age;}//属性String name;char sex;int age;//方法public void sayHi(){System.out.println("您好,我叫"+name+", 今年"+age+"岁,性别是"+sex);}
}//编写学生子类继承人的父类
class Student extends Person{//构造方法public Student(){}public Student(String name,char sex,int age,int id){/*this.name = name;//也可以编写为super.name = namethis.sex = sex;this.age = age;*///以上三条语句,也可以编写为如下:/*super.name = name;super.sex = sex;super.age = age;*///以上三条语句,也可以编写为调用父类的带三个参数构造方法完成,使用super关键字//super();//调用父类无参构造方法super(name,sex,age);this.id = id;}//编写独有属性int id;//独有方法:学习public void study(){System.out.println(name+"正在学习继承课程。。。");}//重写父类的sayHi方法/*public void sayHi(){//System.out.println("您好,我叫"+name+", 今年"+age+"岁,性别是"+sex+",学号是"+id);//注意:1.如果访问实例变量时,默认前面加this.,但是当使用this.访问实例变量时,先在当前类找该属性,如果没有找到该属性则再去父类中找//System.out.println("您好,我叫"+this.name+", 今年"+this.age+"岁,性别是"+this.sex+",学号是"+this.id);//注意:2.如果在子类中访问父类中实例变量,则可以直接使用super关键字,super表示超类也就是父类//System.out.println("您好,我叫"+super.name+", 今年"+super.age+"岁,性别是"+super.sex+",学号是"+this.id);//输出四个信息,但是前三个信息在父类的sayHi中,直接调用父类方法,然后再输出子类的独有信息//sayHi();//等价于 this.sayHi(); //并没有完成调用父类的sayHi方法//解决办法:如果子类重写父类的方法,此时想再调用父类中的sayHi方法,只能使用super.super.sayHi();System.out.println("学号是"+id);}*///完成输出学生四个信息public void print(){//前三个信息调用父类的sayHi方法this.sayHi();//等价于sayHi(),现在当前类中找,如果没找到再去父类中找System.out.println("学号是"+id);}
}//编写学生测试类
class StudentsTest{public static void main(String[] args){//实例化学生//Student stu = new Student();/*stu.sayHi();stu.study();*///stu.print();//创建学生对象同时执行带四个参数的构造方法Student stu2 = new Student("张三",'男',19,1001);stu2.print();}
}
10.2 当实例化子类时父类做了什么
- 先执行父类的构造方法,然后再执行子类的相匹配构造方法
- 如果子类构造方法中没有指明则默认调用父类无参构造方法
- 如果子类构造方法中指明调用父类哪个构造方法,则先执行父类相匹配的构造方法,然后再执行子类相匹配构造方法
- 建议:当手动编写构造方法时,先编写无参构造方法,再编写所需要的构造
class Animal{public Animal(){System.out.println("执行了父类的无参构造");}public Animal(String name,int age,String color){this.name = name;this.age = age;this.color = color;System.out.println("执行了父类的带三个参数构造");}//属性String name;int age;String color;//方法:显示信息public void show(){System.out.println("名字:"+name+"\n年龄:"+age+"\n颜色:"+color);}public Object getInfo(){return null;}
}
//编写狗的子类继承动物父类
class Dog extends Animal{//构造方法//注意:1.当实例化子类时,先跳到子类相匹配的构造方法,如果当前子类构造方法中没有指明调用父类哪个构造方法,则默认调用父类的无参构造方法public Dog(){System.out.println("执行了Dog子类的无参构造方法");}public Dog(String strain){//super();//等价于默认不编写super("未知",5,"未知");this.strain = strain;System.out.println("执行了Dog子类的带一个参数的构造方法");}/*public Dog(String name,int age,String color,String strain){this.name = name;this.age = age;this.color = color;this.strain = strain;System.out.println("执行了Dog子类的带四个参数构造方法");}*///注意:2.如果子类构造方法中使用super关键字指定调用父类哪个构造方法时,则先执行父类相匹配的构造方法public Dog(String name,int age,String color,String strain){super(name,age,color);this.strain = strain;System.out.println("执行了Dog子类的带四个参数构造方法");}//编写子类中独有属性和方法String strain;//重写也叫覆盖override:在子类中重写父类的方法,必须与父类的方法名称一致、参数列表一致、返回类型一致、修饰符一致public void show(){//在子类中可以直接访问父类中的属性(前提:父类中属性没有使用private修饰)System.out.println("名字:"+name+"\n年龄:"+age+"\n颜色:"+color+"\n品种:"+strain);}//重写父类的getInfo方法public String getInfo(){return "OK";}
}
//编写测试类
class Test{public static void main(String[] args){//创建狗的对象Dog dog = new Dog();//显示信息//d.show();//先在Dog类中找show方法,如果没有找到则到父类中找Dog dog2 = new Dog("土狗");Dog dog3 = new Dog("二哈",3,"白色","哈士奇");}
}
继承案例
案例:
某汽车租赁公司有多种汽车可以出租,计算汽车的租金
Vehicle是所有车的父类,属性:品牌、车牌号
方法:返回总租金的方法:public double getSumRent(int days){}
Car:小轿车类是Vehicle类的子类,属性:车型(两厢、三厢、越野)
两厢:每天300,三厢:每天350,越野:每天500
Bus:多座汽车,属性:座位数
座位数<=16,每天400
座位数>=16,每天600
测试类:
根据用户选择不车,计算总租金并输出总租金
class Vehicle{//属性String brand;String id;//构造方法public Vehicle(){}public Vehicle(String brand,String id){this.id = id;this.brand = brand;}//方法:返回总租金的方法:public double getSumRent(int days){return 0;}
}
//编写小轿车子类继承的父类
class Car extends Vehicle{//编写独有属性String type;//构造方法public Car(){super();this.type = "三厢";}public Car(String brand,String id,String type){super(brand,id);this.type = type;}//重写父类的总租金方法public double getSumRent(int days){//判断,根据车型获取日租金switch(this.type){//注意:当type属性没赋值时,该值为null,在java中,switch表达式中如果为null就会出现空值异常case "两厢":return 300 * days;case "三厢":return 350 * days;default:return 500 * days;}}
}
//编写小轿车测试类
class CarTest{public static void main(String[] args){//实例化小轿车Car c = new Car();System.out.println("总租金:"+c.getSumRent(3));}
}
10.3 多态
多态语法格式
- 父类类名 引用名称 = new 子类类名();
- 当是多态时,该引用名称只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
多态:
将多个对象调用同一个方法,得到不同的结果
满足多态的条件:
- 子类必须继承父类
- 子类重写父类的方法
- 父类类名 引用名称 = new 子类类名();
class Vehicle{//属性String brand;String id;//构造方法public Vehicle(){}public Vehicle(String brand,String id){this.id = id;this.brand = brand;}//方法:返回总租金的方法:public double getSumRent(int days){return 0;}public void print(){System.out.println("OK");}
}
//编写小轿车子类继承的父类
class Car extends Vehicle{//编写独有属性String type;//构造方法public Car(){super();this.type = "三厢";}public Car(String brand,String id,String type){super(brand,id);this.type = type;}//重写父类的总租金方法public double getSumRent(int days){//判断,根据车型获取日租金switch(this.type){//注意:当type属性没赋值时,该值为null,在java中,switch表达式中如果为null就会出现空值异常case "两厢":return 300 * days;case "三厢":return 350 * days;default:return 500 * days;}}
}
//编写多座汽车类
class Bus extends Vehicle{//属性int seat;//重写获取总租金方法public double getSumRent(int days){if(this.seat <= 16){return 400 * days;}else{return 600 * days;}}
}
//编写小轿车测试类
class CarTest{public static void main(String[] args){//实例化小轿车/*Car c = new Car();System.out.println("总租金:"+c.getSumRent(3));*//*多态的语法格式:父类类名 引用名称 = new 子类类名();注意:当是多态时,该引用名称只能访问父类中的属性和方法,但是优先访问子类重写以后的方法多态:将多个对象调用同一个方法,得到不同的结果*//*Vehicle c = new Car();System.out.println(c.brand);//nullSystem.out.println(c.id);//null//System.out.println(c.type);//出现编译错误,因为引用名称c是父类类型,因此只能访问父类中的属性c.print();//OKSystem.out.println(c.getSumRent(1));//350.0*/Vehicle v;v = new Car();//构成多态System.out.println("总租金:"+v.getSumRent(1));//350.0v = new Bus();System.out.println("总租金:"+v.getSumRent(1));//400.0}
}
10.4 多态好处
减少代码的冗余性
10.5 多态中两种类型转换
- 向上转型,也叫做自动类型转换,构成多态
- 父类类型 引用名称 = new 子类类名();
- 向下转型,也叫强制类型转换
- 当是多态时,并且访问子类独有的属性或方法时,则必须进行向下转型
- 当进行向下转型时,建议先向下判断,当合法则再转为对应类型,则使用instanceof关键字,否则可能会出现类型转换异常java.lang.ClassCastException
class Pet{//方法public void eat(){System.out.println("宠物正在吃东西。。。。。");}
}
//编写狗的子类继承宠物父类
class Dogs extends Pet{//重写父类的eat方法public void eat(){System.out.println("狗正在吃狗粮。。。");}//编写独有的方法:玩飞盘public void play(){System.out.println("狗正在玩飞盘。。。");}
}
//编写猫子类继承宠物父类
class Cats extends Pet{//重写父类的吃的方法public void eat(){System.out.println("猫正在吃猫粮。。。");}//编写独有的方法:抓老鼠public void catchs(){System.out.println("猫正在抓老鼠。。。");}
}
//编写主人类
class Master{/*//方法:喂养狗public void feed(Dogs dog){dog.eat();}//方法:喂养猫public void feed(Cats cat){cat.eat();}*//*总结得到:以上喂养的猫和狗都属于宠物,因此能否编写主人喂养宠物方法*/public void feed(Pet pet){//Pet pet = new Dogs(); Pet pet = new Cats()pet.eat();//优先执行重写以后的}
}
//编写测试类
class Tests{public static void main(String[] args){//创建主人对象Master m = new Master();//创建狗对象Dogs d = new Dogs();//主人喂养宠物m.feed(d);//狗正在吃狗粮。。。m.feed(new Cats());//猫正在吃猫粮。。。}
}
class Test2{public static void main(String[] args){Pet p = new Dogs();//构成多态,也就是向上转型p.eat();//狗正在吃狗粮。。。//p.play();//出现编译错误,父类类型不能访问子类独有属性或方法//解决办法:进行向下转型Dogs d = (Dogs)p;//此时就可以使用引用名称d访问狗中的play方法d.play();//狗正在玩飞盘。。。/*Cats c = (Cats)p;//出现运行错误,原因:当前引用名称p存放的是狗对象的地址,因此不能强制转为猫c.catchs();*///解决办法:当进行向下转型时,建议先向下判断,当合法则再转为对应类型,则使用instanceof关键字if(p instanceof Dogs){Dogs dog = (Dogs)p;dog.play();}else if(p instanceof Cats){Cats cat = (Cats)p;cat.catchs();}}
}
10.6 递归
递归:方法自己调用自己,必须保证有出口
案例:使用递归计算n!
class Method01{//使用递归计算n!public static int mul(int n){if(n == 0 || n == 1){return 1;}return n * mul(n - 1); }public static void main(String[] args){System.out.println(mul(3));//6}
}
java-多态和递归相关推荐
- java多态 降低代码耦合性_深度分析:理解Java中的多态机制,一篇直接帮你掌握!...
Java中的多态 1 多态是什么 多态(Polymorphism)按字面的意思就是"多种状态".在面向对象语言中,接口的多种不同的实现方式即为多态.用白话来说,就是多个对象调用同一 ...
- Java多态-如何理解父类引用指向子类对象
java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是"向上转型". 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过 C ...
- 笔记1——C++多态与Java多态的异同
最近参加网易笔试遇到一个问题,考察了C++ 多态特性,自己查了相关资料学习了相关用法. 一般程序调用的函数地址是在编译期决定了,但是具有多态特性的函数调用地址是在程序运行期才决定. C++与Java多 ...
- 关于java多态中覆盖的理解
在前面一篇文章中,我已经介绍了关于java多态中重载的理解与规则 所以这篇文章主要介绍多态中的覆盖机制. 首先重载与覆盖除了表现方式不同之外,还有运行时间上的不同,重载是在编译期间就已经可以确定好调用 ...
- 什么是Java多态?如何实现Java多态?
java多态这个概念在同学们深入学习java的时候就会被提出,很多同学并不知道是什么意思,如何实现.今天小千就来给大家介绍一下什么是java多态和java如何实现多态. 什么是多态? 指允许不同类的对 ...
- Java学习笔记二十六:Java多态中的引用类型转换
Java多态中的引用类型转换 引用类型转换: 1.向上类型转换(隐式/自动类型转换),是小类型到大类型的转换: 2.向下类型转换(强制类型转换),是大类型到小类型的转换: 3.instanceof运算 ...
- Java 多态、抽象类 笔记
1. Java 多态 多态就是同一个接口,使用不同的实例而执行不同操作. 1.1 多态存在的三个必要条件 继承 重写 父类引用指向子类对象(Parent p = new Child();) 当使用多态 ...
- java 多态_Java 多态
Java多态,在之前的向上转型的文章中已经介绍了使用场景和为什么要通过向上转型实现运行时多态,请先看文章:张舰:Java 向上转型和向下转型 这篇文章主要是总结一下Java多态的概念,具体的例子请参考 ...
- java 多态 降低耦合_java多态
Java多态就是为了降低耦合,方便我们开发的一种特性. 比如我写了一个动物的接口.然后我通过接口实现了猫和狗这个类. 在我需要使用的时候我可以这样实例化对象 动物 w = new 猫. 这就是向上转型 ...
- java多态+多态中隐含的问题
[0]RAEDME 0.1)本文总结于 core java volume 1, 感觉多态中存在的这个问题很新颖,故分享之: [1]继承与is-a法则 1.1)有一个用来判断是否应该设计为继承关系的规则 ...
最新文章
- 电动汽车换电的优缺点分析
- 50~80万项目需求|室内场景三维重建项目
- 在RHEL5下构建基于系统用户的Postfix邮件系统
- Linux基本命令之ls
- MappedByteBuffer VS FileChannel 孰强孰弱?
- Oracle发送邮件存储过程
- Hadoop单机模式安装入门(Ubuntu系统)
- Tomcat配置多个Service,多个同名的应用运行在一个tomcat下
- golang 将对象转换成string_Golang 匿名 struct 解码数据技巧
- SQL 2008 表死锁的解决
- linux live cd 定制,如何创建定制的Ubuntu Live CD或者USB的简易方式
- 广义线性模型解读必看文章
- 第三方PDF查看--本地查看
- 程序员面试中一面、二面、三面有什么区别?
- maven 系列 06 - 向本地仓库导入jar包 (例如 - pinyin4j-2.5.0)
- 笔记本怎么编html,笔记本win7深度技术旗舰版使用记事本编辑和运行html代码的方法...
- C语言数据类型重新认识
- 最大熵模型怎么理解?熵是什么??
- slf4j-log4j error级别日志发送邮件配置
- 处理打包后的.air文件不能打开的情况