封装继承多态
1.封装
1)对成员变量或者方法前加private
2)对于成员变量生成setter和getter
----
拓展:
3)无参构造 有参构造
4)toString() 为了让sout输出
2.继承
1)A extends B
-----
拓展:
创建对象的过程
1)super() 执行父类构造方法
2)初始化成员变量
3)执行构造方法里的逻辑
3.写面向对象的类的过程
1)写类
2)属性私有化
3)无参构造 有参构造
4)setter getter方法
5)toString()
4.快捷键
1)类的setter个getter方法:Alt+Insert get set Ctrl+A 回车
2)构造方法:
Alt+Insert Constructor
无参 按两下Tab 回车
有参 Ctrl+A 回车
3)toString()
Alt+Insert toString() 回车
5.this和super的区别:
1.this:本类对象 super:代表父类的对象
2.用法
1.this
1.this.成员变量名 当前对象的属性
2.this.成员方法(参数,...) 当前对象的方法
3.this(参数1,参数2,...) 调用本类的有参构造方法
4.this() 调用本类的无参构造方法 必须写在第一行
2.super
1.super.成员变量名 父类对象的属性
2.super.成员方法(参数,...) 父类对象的方法
3.super(参数1,参数2,...) 调用父类的有参构造方法
4.super() 调用父类的无参构造方法 必须写在第一行
3.this()与super不能共存
3.多态
. 0.引子
1.方案一:张女士喂小动物
1.创建类Women feed(Dog dog) {} feed(Cat cat ){} 方法
2.创建Dog类 eat(){}方法
3.创建Cat类 eat(){}方法
4.创建测试类
1.创建Women对象
2.创建Dog对象
3.创建Cat对象
4.调用Women对象.feed(Dog对象)
5.调用Women对象.feed(Cat对象)
5.增加Monkey对象
1.创建Monkey类 eat(){}方法
2.类Women 增加 feed(Monkey monkey) {} 方法
6.有什么不足
每增加一个小动物,就需要Women增加feed()方法(修改源代码),不利于扩展
2.方案二:张女士喂小动物(方案一改良版本:多态版本)
1.增加小动物的父类Animal: eat()
2.让所有的小动物都继承Animal
3.类Women只保留一个方法 feed(Animal animal);//实现喂食所有的动物
• 1、多态概念
一种行为,有多种不同的表现形式.
Java中多态的具体体现
• 方法重载
• 方法覆盖
• 多态参数(新内容,重点、难点)
• 2、方法的重载(Overload)
1)方法重载的概念:
在Java类中如果有多个同名但是参数不同的方法就称为“方法的重载”。
编译器会根据调用时传递的实际参数自动判断具体调用的是哪个重载方法。
2)方法重载的三大原则:
①方法名相同
②参数不同(可以有三方面的不同,数量不同、类型不同、顺序不同)
③同一作用域(同一个类)
注意:方法重载跟方法的返回值类型没有任何关系,只有返回值不同的方法不能构成重载。
请勿将功能完全不一样的方法进行重载!
3)方法重载的好处:
方便于阅读及程序的维护,优化了程序设计。
4)方法重载示例
在一个类中,需要实现求两个整数和,两个浮点数和的方法,这两个方法如何定义
public class Test1 {
public int add(int a,int b){
System.out.println("Test1.add(int a,int b)");
return a+b;
}
public float add(float a,float b){
System.out.println("Test1.add(float a,float b)");
return a+b;
}
public static void main(String[] args) {
Test1 test1 = new Test1();
int add = test1.add(1, 3);
System.out.println("add = " + add);
float add1 = test1.add(10.0f, 20.0f);
System.out.println("add1 = " + add1);
}
}
• 3、对象向上造型
1)定义:子类类型自动转换为父类类型,不需要强转.父类型的引用指向子类对象,对象向上造型也叫自动类型提升
2)作用:提高程序的可扩展性
3)案例
1.dog对象 可以调用狗类中的所有方法(包括父类宠物类中所有非私有的方法)
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Dog dog = new Dog();
dog.toHostpital();
dog.shout();
dog.m1();
}
}
2.Pet p= new Dog() //父类的引用指向子类的对象--向上造型
p只能调用宠物类Pet中定义的方法,狗类扩展的新方法不能调用
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet p=new Dog();
p.m1();
p.toHostpital();
// p.shout();//不能调用子类扩展的方法
}
}
• 4、多态环境下对属性和方法的调用
1)多态环境下对非静态方法的调用
父类型 变量名=new 子类型();
pet对象: 编译看左边 ,运行看右边
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet p=new Dog();//父类型的引用指向子类对象
p.m1();//子类没重写调用的是父类的方法
p.toHostpital();//子类重写方法调用的是子类对象重写的方法
}
}
2)多态性的情况下对静态成员方法的调用
对静态成员方法的调用:编译运行都看左边
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
public static void m2(){
System.out.println("Pet.m2()static方法");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
public static void m2(){
System.out.println("Dog.m2()static方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet pet =new Dog();
pet.m2();//静态的成员方法编译运行都看左边,调用的是父类的m2()方法
}
}
3)成员变量
class Pet{
int num = 3;
}
class Dog extends Pet{
int num = 4;
}
Pet pet = new Dog()
System.out.println( pet.num ) ; //调用的是宠物类中的成员变量,输出是3,说明调用的是父类的成员变量的值
对成员变量的调用:编译运行都看左边。
注意:变量不存在被子类覆写这一说法,只有方法存在覆写。
所以,静态变量也是编译和运行都看等号左边。
4)结论
编译期和运行期相同的情况:A a = new A();
• 编译期和运行期不同的情况;
• 父类和子类有相同的成员变量(静态和非静态),多态下访问的是父类的成员变量。
• 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的
是子类的成员方法。
• 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问
的是父类的静态方法
• 5、多态参数
1)定义:方法的形式参数类型是父类类型,而传递的实际参数可以是该父类任意子类的对象
2)方法参数多态性的好处:提高代码的扩展性
总结:
1.多态:一种行为,有多种不同形式的表现
2.多态的具体体现
1.方法重载
2.方法覆盖
3.多态参数
3.方法重载:同一个类中有多个同名的方法,但是参数不同(参数的类型不同,参数的顺序不同,参数的个数不同),叫做方法的重载
4.对象向上造型:子类类型自动转换为父类类型,不需要强转
5.多态环境下对属性和方法的调用
1)多态环境下对非静态方法的调用
父类型 变量名=new 子类型();
pet对象: 编译看左边 ,运行看右边
2)多态性的情况下对静态成员方法的调用
对静态成员方法的调用:编译运行都看左边
3)多态性的情况下对非静态成员变量,静态成员变量的调用
对非静态,静态成员方法的调用:编译运行都看左边
换言之:
编译期和运行期不同的情况;
• 父类和子类有相同的成员变量(静态和非静态),多态下访问的是父类的成员变量。
• 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的
是子类的成员方法。
• 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问
的是父类的静态方法
6.多态参数:方法的形式参数类型是父类类型,而传递的实际参数可以是该父类任意子类的对象
7.多态作为返回值类型:返回值是父类型的引用,方法体的return返回的是子类对象
• 6、多态的前提与及弊端
1.多态的前提:类之间有关系:继承或者实现
2.多态的弊端:只能调用父类的方法,不能调用子类特有的方法
• 7、对象向下造型
1.定义:父类型引用转换为子类型
2.公式:子类型 变量名=(子类型)父类型变量名
3.作用:为了使用子类中特有的方法
Dog d=(Dog)p;//向下造型
d.shout();//能调用子类扩展的方法
• 8、多态的注意事项
1.不能把父类向下转换为子类类型 Pet pet=new Pet(); Dog dog=(Dog)pet;
2.不具备继承关系的类不能互转
Pet p=new Cat();//父类型的引用指向子类对象
Dog d=(Dog)p;//不具有继承关系的类不能互转 Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to Dog
3.对于转型,只能强制转换成这个对象的运行期类型
Pet p=new Dog();//父类型的引用指向子类对象
Dog d=(Dog)p;//向下造型:只能强制转换成这个对象的运行期类型
总结:
1)多态转型:
•向上造型(自动)
•向下造型(强制)
2)多态向上转型的特点:•限制了对子类特有方法的访问,提高代码的扩展性
3)多态向下转型的特点:•为了使用子类特有方法
• 9、instanceof运算符
1)作用:运算符instanceof用来判断对象是否属于某个类的实例
2)公式:对象名 instanceof 类名
该表达式为一个boolean表达式,如果对象的类型是后面提供的类或其子类,则返回true,反之返回false
3)案例:
1.Animal eat()
1.Dog:eat() lookingHome()
2.Cat:eat() catchMouse()
2.AnimalTest
判断Dog类型或者Cat类型
3.代码:
public class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
package t01;
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗啃骨头");
}
public void lookingHome(){
System.out.println("狗看家");
}
}
package t01;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
package t01;
public class AnimalTest {
public static void main(String[] args) {
//创建对象
Animal animal=new Cat();
animal.eat();
//判断是否是狗对象类型
if (animal instanceof Dog){
//强转
Dog dog= (Dog) animal;
//调用特有的方法
dog.lookingHome();
}
if (animal instanceof Cat){
//强转
Cat cat= (Cat) animal;
//调用方法
cat.catchMouse();
}
}
}
3)案例:
需求说明:
主人和狗狗玩接飞盘游戏,狗狗健康值减少10,与主人亲密度增加5
主人和企鹅玩游泳游戏,企鹅健康值减少10,与主人亲密度增加5
•提示:
Dog类添加catchingFlyDisc()方法,实现接飞盘功能
Penguin类添加swimming()方法,实现游泳功能
主人添加play(Pet pet)方法
如果pet代表Dog就玩接飞盘游戏
如果pet代表Penguin就玩游泳游戏
思路:
1.设计类
1.Pet health love
1.Dog:catchingFlyDisc()
2.Penguin:swimming()
2.Master:play(Pet pet)方法
如果pet代表Dog就玩接飞盘游戏
如果pet代表Penguin就玩游泳游戏
3.MasterTest
总结:
多态在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法•
多态存在的三个必要条件
•继承
•重写覆盖
•对象向上造型-父类引用指向子类对象
1.多态作为参数类型:参数的形参是父类型的引用,调用的时候传递的实参是子类型的对象
设计类:类之间关系
1.Pet:name eat(food)
1.Dog 重写Pet类的eat(food)
2.Cat 重写Pet类的eat(food)
2.Food:name
1.Bone
2.Fish
3.Master
feed(Pet pet,Food food)
4.MaterTest测试类
1.创建两只宠物对象
2.创建食物对象
3.创建Master对象
4.调用Master对象的feed(宠物对象,食物对象)
2.多态作为返回值类型:返回值是父类型的引用,方法体的return返回的是子类对象
设计类:类之间关系
1.Car:name,color,构造方法(有参,无参) 方法:运行
1.Bmw extends Car,构造方法(有参,无参) 方法:重写运行方法
2.Benz extends Car,构造方法(有参,无参) 方法:重写运行方法
3.Bsj extends Car,构造方法(有参,无参) 方法:重写运行方法
2.CarFactory:汽车工厂
public static Car makeCar(){
//根据随机数返回不同的汽车类型的对象
}
3.CarTest测试类
1.Car car=CarFactory.makeCar();
2.调用方法
car.run()
-------------------------------
作业思路
1.多态作为参数类型:参数的形参是父类型的引用,调用的时候传递的实参是子类型的对象
设计类:类之间关系
1.Pet:name eat(food)
1.Dog 重写Pet类的eat(food)
2.Cat 重写Pet类的eat(food)
2.Food:name
1.Bone
2.Fish
3.Master
feed(Pet pet,Food food)
4.MaterTest测试类
1.创建两只宠物对象
2.创建食物对象
3.创建Master对象
4.调用Master对象的feed(宠物对象,食物对象)
2.多态作为返回值类型:返回值是父类型的引用,方法体的return返回的是子类对象
设计类:类之间关系
1.Car:name,color,构造方法(有参,无参) 方法:运行
1.Bmw extends Car,构造方法(有参,无参) 方法:重写运行方法
2.Benz extends Car,构造方法(有参,无参) 方法:重写运行方法
3.Bsj extends Car,构造方法(有参,无参) 方法:重写运行方法
2.CarFactory:汽车工厂
public static Car makeCar(){
//根据随机数返回不同的汽车类型的对象
}
3.CarTest测试类
1.Car car=CarFactory.makeCar();
2.调用方法
car.run()