day15
class Animal{
//属性
String name;
int age;
String color;
//方法:显示信息
public void show(){
System.out.println("名字:"+name+"\n年龄:"+age+"\n颜色:"+color);
}
}
//编写狗的子类继承动物父类
class Dog extends Animal{
//编写子类中独有属性和方法
String strain;、
//重写也叫做覆盖override:在子类中重写父类的方法,必须与父类的方法名称一致,参数列表一致、返回类型一致、修饰符一致
public void show(){
//在子类可以直接访问父类中的属性(前提:父类中属性没有使用private修饰)
System.out.println("名字:"+name+"\n年龄:"+age+"\n颜色:"+color+"\n品种:"+strain);
}
}
//等价于
/*class Dog extends object{
}*/
class Cat extends Animal{
//独有属性:性别
char sex;
}
1.重写
----子类方法名称必须与父类方法名称一致
---参数列表一致
---返回类型一致或父类方法返回类型的子类类型
---修饰符不能缩小范围
子类不能重写:
---构造方法不能重写
---属性不能重写
---静态方法不能重写
---私有方法不能重写
//编写测试类
class Test{
public static void main(String[] args){
//创建狗的对象
Dog d=new Dog();
//显示信息
d.show();//先在Dog类中找show方法,如果没有找到则再去父类中找
}
}
2.this与super关键字访问实例变量区别
this 关键字---代表当前这个对象
---this可以访问本类中的实例变量,实例方法也可以访问本类中
的其他构造方法
---this还可以访问父类中的实例变量
super关键字---表示超类
---super只能在子类中使用,可以访问父类中的实例变量
注意:--如果访问实例变量时,默认前面添加this,但是使用this.访问实例变量时
先在当前类中找该属性
--使用super直接去父类中找该属性或方法
--使用super访问父类的构造方法
class Student extends Person{
//无参构造
public Student(){
}
public Student(String name,char sex,int age,int id){
super(name,sex,age);//父类构造了此方法,直接调用
this.id=id;
}
}
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;
thid.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 is,String type){
super(brand,id);
this.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));
}
}
4.多态:
---多态语法格式:
--父类类名 引用名称=new 子类类名();
--当是多态时,该引用名称只能访问父类中的属性和方法,
但是优先访问子类重写以后的方法;
---多态:将多个对象调用一个方法,得到不同的结果;
---满足多态的条件:
--子类必须继承父类;
--子类重写父类的方法;
--父类类名 引用名称=new 子类类名();
class Test{
/*
多态的语法格式:
父类类名 引用名称=new 子类类名();
注意:当是多态时,该引用名称只能访问父类中的属性和方法啊,但是优先访问子类重写以后的方法
*/
Vehicle c=new Car();
System.out.println(c.brand);//null
System.out.println(c.id);null
//System.out.println(c.type);//出现编译错误,因为引用名称c是父类类型,因此只能访问父类中的属性
c.print();//ok,在父类中定义了此方法
System.out.println(c.getSumRent(1));
}
5.多态的好处:减少代码的冗余性
6.为什么要进行类型的转换:
---多态中的两种类型转换
--向上转型:也叫做自动类型转换
父类类型 引用名称=new 子类类名();
--向下转型:也叫做强制类型转换
当是多态时,并且访问子类独有的属性或方法,则必须进行
向下转型
实例:
class Pet{
//方法
public void eat(){
System.out.println("宠物正在吃东西.....");
}
}
//编写狗的子类继承宠物父类
class Dog extends Pet{
//重写父类的eat方法
public void eat(){
System.out.println("狗正在吃狗粮....");
}
//编写独有的方法:玩飞盘
public void play(){
System.out.println("狗正在玩飞盘....");
}
}
//编写猫的子类继承宠物父类
class Cat extends Pet{
//重写父类的吃的方法
public void eat{
System.out.println("猫正在吃猫粮....");
}
//编写独有的方法:抓老鼠
public void catching(){
System.out.println("猫正在抓老鼠....");
}
}
//编写主人类
class Master{
//方法:喂养狗
/*public void feed(Dog dog){
dog.eat();
}
public void feed(Cat cat){
cat.eat();
}*/
/*
总结得到:以上喂养猫和狗都属于宠物,因此能否编写主人喂养宠物方法
*/
public void feed(Pet pet){//Pet pet=new Dog(); Pet pet=new Cat()
pet.eat();
}
}
//测试类
class Test{
public static void main(String[] args){
//创建主人对象
Master m=new Master();
//创建狗对象
Dog d=new Dog();
//主人喂养宠物
m.feed(d);
m.feed(new Cat());
}
}
class Test2{
public static void main(String[] args){
Pet p=new Dog();//构成多态;也就是说向上转型
/*p.eat();
//p.play();// 出现编译错误,父类类型不能访问子类独有属性或方法
//解决办法:进行向下转型
Dog d=(Dog)p;
//此时就可以使用引用名称d访问狗中的play方法
d.play();
*/
/*Cat c=(Cat)p;//出现运行错误,原因:当前引用名称p存放的是狗对象的地址,因此不能强制转换为猫
c.catching();*/
//解决办法:当进行向下转型时,建议先进行判断,当合法则在转为对应的类型,则使用instanceof关键字
p=new Cat();
if(p instanceof Dog){
Dog dog=(Dog)p;
dog.play();
}else if(p instanceof Cat){
Cat cat=(Cat)p;
cat.catching();
}
}
}