Day10
多态
多态的概述及其代码体现
/*
A:多态概述(polymorphic)
*事物存在的多种形态;
B:多态前提
*要有继承关系;
*要有方法重写;
*要有父类引用指向子类对象;
C:案例演示
*代码体现多态
*/
class Demo1_Polymorphic {
public static void main(String[] args) {
Cat c = new Cat();
c.eat();
Animal a = new Cat(); //父类引用指向子类对象
a.eat();
}
}
class Animal{
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
}
多态的成员访问特点之成员变量
/*
*成员变量
*编译看左边(父类),运行看左边(父类)
*/
class Demo2_Polymorphic {
public static void main(String[] args) {
Father f = new Son(); //父类引用指向子类对象;
System.out.println(f.num);
Son s = new Son();
System.out.println(s.num);
}
}
class Father {
int num = 10;
}
class Son extends Father {
int num = 20 ;
}
多态中的访问特点之成员方法
/*
成员方法
编译看左边(父类),运行看右边(子类)(动态绑定)
*/
class Demo2_Polymorphic {
public static void main(String[] args) {
/*Father f = new Son(); //父类引用指向子类对象;
System.out.println(f.num);
Son s = new Son();
System.out.println(s.num); */
Father f = new Son();
f.print();
}
}
class Father {
int num = 10;
public void print (){
System.out.println("father");
}
}
class Son extends Father {
int num = 20 ;
public void print (){
System.out.println("son");
}
}
多态访问特点之静态成员方法
/*静态方法
*编译看左边(父类),运行看左边(父类);
*(静态和类相关,算不上重写,所以还是看左边);
*只有非静态的成员方法,编译看左边,运行看右边;
*/
多态中的向上和向下转型
class Demo3_SuperMan {
public static void main(String[] args) {
Person p = new SuperMan(); //父类引用指向子类对象
//父类引用指向子类对象,就是向上转型
System.out.println(p.name); //体现父类属性;
p.business(); //调用子类方法
SuperMan s = (SuperMan)p ; //向下转型
s.fly();
/*
基本数据类型自动类型提升和强制类型转换
int i = 10;
byte b = 20;
i = b; //自动类型转换
b = (byte)i; //强制类型转换
*/
}
}
class Person {
String name = "John";
public void business(){
System.out.println("谈生意");
}
}
class SuperMan extends Person {
String name = "superman";
public void business(){
System.out.println("谈几个亿的大单");
}
public void fly(){
System.out.println("飞出去救人");
}
}
多态的好处和弊端
/*A:多态的好处
a:提高了代码的维护性(继承保证);
b:提高了代码的扩展性(由多态保证);
B:多态的弊端
*不能使用子类特有的属性和行为;
C:案例演示*/
class Demo4_Animal {
public static void main(String[] args) {
method(new Cat());
method(new Dog());
}
Animal a = new Cat();
//开发的时候很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象更方便,可以使用子类中的特有属性
/*public static void method(Cat c){
c.eat() ;
}
public static void method(Dog d){
d.eat() ;
*/
//若果把狗强制转换成猫就会出现类型转换异常, ClassCastException: Dog cannot be cast to Cat
public static void method(Animal a){ //当做参数的时候用多态,因为扩展性强
/*Cat c = (Cat)a;
c.eat();
c.catchMouse();
*/
//关键字 instanceof 判断前边的引用是否是后边的数据类型
if (a instanceof Cat) {
Cat c = (Cat)a;
c.eat();
c.catchMouse();
} else if (a instanceof Dog) {
Dog d = (Dog)a;
d.eat();
d.watchDog();
} else {
a.eat();
}
}
}
class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
public void watchDog(){
System.out.println("看家护院");
}
}
多态案例演示
class Test1_Polymorphic {
public static void main(String[] args) {
Fu f = new Zi();
//f.method();
Zi z = (Zi)f;
z.method();
f.show();
}
}
class Fu {
public void show(){
System.out.println("fu show");
}
}
class Zi extends Fu {
public void show(){
System.out.println("Zi show");
}
public void method(){
System.out.println("Zi method");
}
}
class Test2_Polymorphic {
public static void main(String[] args) {
A a = new B();
a.show();
B b = new C();
b.show();
}
}
class A {
public void show(){
show2();
}
public void show2(){
System.out.println("我");
}
}
class B extends A {
public void show2(){
System.out.println("爱");
}
}
class C extends B {
public void show(){
super.show();
}
public void show2(){
System.out.println("你");
}
}
抽象类
抽象类的概述及其特点
A:抽象类概述:
*抽象就是看不懂的;
B:抽象类特点:
*a:抽象类和抽象方法必须用abstract关键字修饰;
* abstract class 类名{}
* public abstract void eat();
*b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者接口;
*c:抽象类如何实例化:
*按照多态的方式,用具体的子类实例化,其实这也是多态的一种,抽象类多态
*d:抽象类的子类
*要么是抽象类
*要么重写抽象类中所有抽象方法;
C:案例演示
*抽象类特点
class Demo1_Abstract {
public static void main(String[] args) {
//Animal a = new Animal(); //错误: Animal是抽象的; 无法实例化
Animal a = new Cat();
a.eat();
}
}
abstract class Animal { //抽象类
public abstract void eat(); //抽象方法
}
class Cat extends Animal{
/*public void eat(){
System.out.println("猫吃鱼");
}*/
}
抽象类的成员特点
/*
*A:抽象类的成员特点:
*a:成员变量:既可以是变量,也可以是常量,abstract是否可以修饰成员变量? 不能修饰成员变量;
*b:构造方法:有
*用于子类访问父类的初始化;
*B:案例演示
*抽象类的成员特点
*C:抽象类的成员方法特性:
*a:抽象方法:强制要求子类做的事情;
*b:非抽象方法,子类继承的事情,提高代码的复用性;
*/
class Demo2_Abstract {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
abstract class Demo {
int num = 10;
final int NUM = 20;
public void print(){
System.out.print("111");
}
public abstract void method();
}
class Test extends Demo {
public void method(){
System.out.println("111");
}
}
抽象类练习
class Test1_Animal {
public static void main(String[] args) {
Cat c = new Cat("加菲", 8);
System.out.println(c.getName() + "----" +c.getAge());
c.eat();
c.catchMouse();
Dog d = new Dog("八公",30);
System.out.println(d.getName() + "----" +d.getAge());
d.eat();
d.watchDog();
}
}
abstract class Animal {
private String name ; //姓名
private int age; //年龄
public Animal(){};
public Animal(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public abstract void eat();
}
class Cat extends Animal{
public Cat(){};
public Cat(String name ,int age) {
super(name,age);
}
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public Dog(){};
public Dog(String name ,int age) {
super(name,age);
}
public void eat(){
System.out.println("狗吃肉");
}
public void watchDog(){
System.out.println("看家护院");
}
}
class Test2_Teacher {
public static void main(String[] args) {
BaseTeacher bt = new BaseTeacher("冯佳",23);
bt.teach();
}
}
abstract class Teacher {
private String name ; //姓名
private int age; //年龄
public Teacher(){};
public Teacher(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public abstract void teach() ;
}
class BaseTeacher extends Teacher{
public BaseTeacher(){};
public BaseTeacher(String name,int age){
super(name,age);
}
public void teach(){
System.out.println("我的姓名是" + this.getName() + ";我的年龄是:" + super.getAge() + ",讲课内容是Java基础");
}
}
//项目经理和程序员类
class Test_Employee {
public static void main(String[] args) {
Coder c = new Coder("啦啦啦啦","007",20000);
c.work();
Manger m = new Manger("苍老师","9527",8000,20000);
m.work();
}
}
abstract class Employee {
private String name;
private String id;
private double salary;
public Employee(){};
public Employee(String name,String id,double salary){
this.name = name;
this.id = id;
this.salary = salary;
}
public void setName(String name){
this.name =name;
}
public String getName(){
return name;
}
public void setId(String id){
this.id = id;
}
public String getId(){
return id;
}
public void setSalary(double salary){
this.salary =salary;
}
public double getSalary(){
return salary;
}
public abstract void work();
}
class Coder extends Employee{
public Coder(){};
public Coder(String name,String id,double salary){
super(name,id,salary);
}
public void work(){
System.out.println("我的姓名是:" + this.getName() +",我的工号是:" + this.getId() + ",我的工资是:" + this.getSalary() + ",我的工作内容是敲代码");
}
}
class Manger extends Employee {
private int bonus;
public Manger(){};
public Manger(String name,String id,double salary,int bonus){
super(name,id,salary) ;
this.bonus = bonus;
}
public void work(){
System.out.println("我的姓名是:" + this.getName() +",我的工号是:" + this.getId() + ",我的工资是:"
+ this.getSalary() + ",我的奖金是:" + bonus +",我的工作内容是项目协调");
}
}
抽象类中的面试题
A:面试题1
*一个抽象类没有抽象方法,可不可以定义为抽象类?如果可以,有何意义?
可以,这么做的目的是不让其他类创建本类对象,交给子类完成;
B:面试题2
*abstract不能和哪些关键字并存?
abstract 和static不能并存 //被abstract修饰的方法没有方法体;被static修饰的可以用类名.调用,但是类名.调用抽象方法是没有意义的;
abstract 和final
//被abstract修饰的方法强制子类重写,被final修饰的方法不允许子类重写;
abstract和private
//被abstract修饰的是为了让子类看到并强制重写; 被private修饰不让子类访问,所以他俩是矛盾的
接口
接口的概述及其特点
A:接口概述
*从狭义的角度讲就是Java中的interface;
*从广义的角度来讲对外提供规则的都是接口;
B:接口特点
*a:接口用关键字interface表示;
*interface 接口名{};
*b:类实现接口用implements表示
*class 类名 implements 接口名{}
*c:接口不能实例化
*那么,如何接口实例化呢?
*按照多态的方式实例化;
*d:接口的子类
*a:可以是抽象类,但是意义不大;
*b:可以是具体类,要重写接口中所有抽象方法.(推荐方案)
C:案例演示
*接口特点
class Demo1_Interface {
public static void main(String[] args) {
//Inter i = new Inter(); //接口不能被实例化,因为调用抽象方法没有意义
Inter i = new Demo(); 父类引用指向子类对象
i.print();
}
}
interface Inter {
public abstract void print(); //接口中的方法都是抽象的;
}
class Demo implements Inter {
public void print(){
System.out.println("print");
}
}
接口的成员特点
*成员变量:只能是常量,并且是静态的并公共的;
*默认修饰符 public static final //三个关键字不分顺序;
*构造方法:接口没有构造方法;
*成员方法:默认是public和abstract
*默认修饰符:public abstract;
*建议:手动给出
class Demo2_Interface {
public static void main(String[] args) {
Demo d = new Demo();
d.print();
System.out.println(Inter.num);
}
}
interface Inter {
public static final int num = 10;
/*public void print(){
} */ //接口中不能定义非抽象方法;
//public Inter(){}; 接口中的工作方法;
}
class Demo implements Inter { //一个类不写继承任何类,默认继承Object类
public void print(){
//num = 20;
System.out.println(num);
}
}
类与类,类与接口,接口与接口的关系
/*
*A:类与类,类与接口,接口与接口的关系
*a:类与类
*继承关系,只能单继承,可以多层继承;
*b:类与接口:
*实现关系,可以单实现,也可以多实现;
*c:接口与接口
*继承关系,可以单继承,也可以多继承
*/
interface InterA {
public abstract void printA();
}
interface InterB {
public abstract void printB();
}
interface InterC extends InterB,InterA {
public abstract void printC();
}
//class Demo implements InterA,implements InterB { //这么做不允许,是非法的;
class Demo implements InterA,InterB {
public void printA(){
System.out.println("printA");
}
public void printB(){
System.out.println("printB");
}
}
抽象类和接口的区别
/*
A:成员区别
*抽象类
*成员变量:可以是变量,也可以是常量;
*构造方法:有
*成员方法:可以抽象,也可以非抽象;
*接口
*成员变量:只能是常量;
*成员方法:只可以是抽象
B:关系区别
*类与类 :继承:单继承,多层继承;
*类与接口:实现:单实现,多实现
*接口与接口:继承:单继承,多继承
C:设计理念区别:
*抽象类:被继承体现的是"is a"的关系,抽象类中定义的是该继承关系的共性功能;
*接口:被实现体现的是"like a"的关系,接口定义的是继承体系的扩展功能;
*/
案例演示
/*案例演示
*动物类:姓名,年龄,吃飯,睡觉;
*猫和狗
*动物培训接口:调高
*/
class Test2_Animal {
public static void main(String[] args) {
Cat c = new Cat("加菲",8);
c.eat();
c.sleep();
System.out.println(c.getName()+"的年龄是:" + c.getAge());
System.out.println("--------");
JumpCat jc = new JumpCat("跳高猫",3);
jc.eat();
jc.sleep();
jc.jump();
System.out.println(jc.getName()+"的年龄是:" + jc.getAge());
}
}
abstract class Animal {
private String name;
private int age;
public Animal(){};
public Animal(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age){
this.age =age;
}
public int getAge(){
return age;
}
public abstract void eat();
public abstract void sleep();
}
interface Jumping {
public abstract void jump();
}
class Cat extends Animal {
public Cat(){};
public Cat(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("侧着睡");
}
}
class JumpCat extends Cat implements Jumping {
public JumpCat(String name,int age){
super(name,age);
}
public void jump(){
System.out.println("猫跳高");
}
}
class Dog extends Animal {
public Dog(){};
public Dog(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("狗吃肉");
}
public void sleep(){
System.out.println("趴着睡");
}
}
class JumpDog extends Dog implements Jumping {
public JumpDog(String name,int age){
super(name,age);
}
public void jump(){
System.out.println("狗跳高");
}
}