面向对象03
Posted jaro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象03相关的知识,希望对你有一定的参考价值。
1.多态
所谓多态就是事物存在的多种形态
表现形式是父类引用指向子类对象
多态前提:
* a:要有继承关系
* b:要有方法重写
* c:要有父类引用指向子类对象
重写:
就是子类中写了和父类相同的方法,将父类方法覆盖
这样子类在调用该方法时,就直接调用自己的方法,而不是父类的方法
案例:
1 class Demo1_Polymorphic { 2 public static void main(String[] args) { 3 Cat c = new Cat(); 4 c.eat(); 5 6 Animal a = new Cat(); 7 //创建一个动物,这个动物是只猫,这没问题,父类引用指向子类对象 8 a.eat();//这里结果是猫吃鱼 9 } 10 } 11 class Animal { 12 public void eat() { 13 System.out.println("动物吃饭"); 14 } 15 } 16 17 class Cat extends Animal { 18 public void eat() { 19 System.out.println("猫吃鱼"); 20 } 21 }
看看下面的例子:
1 class SuperMan extends Person { 2 String name = "superMan"; 3 4 public void talkTrade() { 5 System.out.println("谈几个亿的大单子"); 6 } 7 8 public void fly() { 9 System.out.println("飞出去救人"); 10 } 11 }
1 public class Person { 2 String name = "John"; 3 public void talkTrade() { 4 System.out.println("谈生意"); 5 } 6 }
1 public class Demo3_SuperMan { 2 public static void main(String[] args) { 3 Person p = new SuperMan();//向上转型 4 System.out.println(p.name);//没有用到多态,调用的是父类的属性 5 p.talkTrade();//只有这里用到了多态,因为只有这里运用的是重写的方法 6 //p.fly(),能这样写吗?是不能的,因为超人被提升为人了,而父类是不能调用子类方法的,这里p是父类对象,只有当满足多态条件时,才会看成子类对象 7 SuperMan sm = (SuperMan)p;//向下转型 8 sm.fly(); 9 } 10 }
运行结果:
John
谈几个亿的大单子
飞出去救人
为什么会出现这个结果,注释中解释了
2.多态中向上转型和向下转型
1 public static void method(Animal a) { 2 //当作参数的时候用多态最好,因为扩展性强 3 //当传入对象是猫或者狗的时候,实际上Animal a = 猫,所以用到多态了 4 //关键字 instanceof 判断前边的引用是否是后边的数据类型 5 if (a instanceof Cat) { 6 Cat c = (Cat)a; 7 c.eat(); 8 c.catchMouse(); 9 }else if (a instanceof Dog) { 10 Dog d = (Dog)a; 11 d.eat(); 12 d.lookHome(); 13 }else { 14 a.eat(); 15 } 16 }
4.关键字abstract
意为抽象,就是看不懂,你不知道
* a:抽象类和抽象方法必须用abstract关键字修饰
* abstract class 类名 {}
* public abstract void eat();//不知道该方法具体是怎么实现的
//比如动物吃,你知道它吃什么吗?怎么吃?都不知道
* b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
* c:抽象类不能实例化那么,抽象类如何实例化呢?
* 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态
* d:抽象类的子类
* 要么是抽象类
* 要么重写抽象类中的所有抽象方法
1 abstract class Animal { //抽象类 2 public abstract void eat(); //抽象方法,子类继承抽象类,抽象方法是强制要重写的,和接口一样,不重写,抽象还有什么意义 3 public Animal() { 4 System.out.println("父类空参构造"); 5 } 6 } 7 class Cat extends Animal { 8 public Cat() { 9 super(); 10 } 11 12 @Override 13 public void eat() { 14 // TODO Auto-generated method stub 15 System.out.println("mao ci yu"); 16 } 17 } 18 class Demo1_Abstract { 19 public static void main(String[] args) { 20 //Animal a = new Animal(); //错误: Animal是抽象的; 无法实例化 21 Animal a = new Cat(); //父类引用指向子类对象 22 a.eat(); 23 } 24 }
运行结果:
父类空参构造
mao ci yu
抽象类的成员特点:
* A:抽象类的成员特点
* a:成员变量:既可以是变量,也可以是常量。abstract是否可以修饰成员变量?不能修饰成员变量
* b:构造方法:有
* 用于子类访问父类数据的初始化
* c:成员方法:既可以是抽象的,也可以是非抽象的
* B:案例演示
* 抽象类的成员特点
* C:抽象类的成员方法特性:
* a:抽象方法,强制要求子类做的事情。
* b:非抽象方法,子类继承的事情,提高代码复用性
1 abstract class Demo { 2 int num1 = 10;//变量 3 final int num2 = 20;//常量 4 5 public Demo(){}//构造方法 6 7 public void print() {//非抽象方法,子类可以直接使用 8 System.out.println("我是码农"); 9 } 10 11 public abstract void method();//抽象方法,子类必须实现 12 } 13 14 class Test extends Demo { 15 public void method() { 16 System.out.println("绝地求生"); 17 } 18 }
* A:面试题1
* 一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
* 可以
* 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成
* B:面试题2
* abstract不能和哪些关键字共存
不能与static,final,final共存
abstract和static
被abstract修饰的方法没有方法体
被static修饰的可以用类名.调用,但是类名.调用没有实现的抽象方法有什么意义
abstract和final
被abstract修饰的方法强制子类重写
被final修饰的不让子类重写,所以他俩是矛盾
abstract和final
被abstract修饰的是为了让子类看到并强制重写
被private修饰不让子类访问,子类都不能访问了,还重写个啥啊
5.接口:
* A:接口概述
* 从狭义的角度讲就是指java中的interface
* 从广义的角度讲对外提供规则的都是接口
* B:接口特点
* a:接口用关键字interface表示
* interface 接口名 {}
* b:类实现接口用implements表示
* class 类名 implements 接口名 {}
* c:接口不能实例化
* 那么,接口如何实例化呢?
* 按照多态的方式来实例化
* d:接口的子类
* a:可以是抽象类。但是意义不大
* b:可以是具体类。要重写接口中的所有抽象方法,代码中无处不在
* A:接口成员特点
* 成员变量只能是常量,并且是静态的并公共的
* 默认修饰符:public static final
* 构造方法:接口没有构造方法
* 成员方法:只能是抽象方法
* 默认修饰符:public abstract
1 public interface Inter { 2 public static final int num = 10;//这里写不写public static final都会默认加上 3 public abstract void print();//这里写不写public abstract都会默认加上,因为写接口本来就是为了实现的啊,会默认加上abstract 4 }
1 class Demo implements Inter { 2 public Demo() { 3 super(); 4 } 5 public void print() { 6 //num = 20;num已经被final修饰了,不能重新赋值 7 System.out.println(num); 8 } 9 }
1 public class Demo2_Interface { 2 public static void main(String[] args) { 3 Demo d = new Demo(); 4 d.print(); 5 System.out.println(Inter.num); 6 } 7 }
运行结果:
10
10
类与类,类与接口,接口与接口的关系:
* A:类与类,类与接口,接口与接口的关系
* a:类与类:
* 继承关系,只能单继承,可以多层继承
* b:类与接口:
* 实现关系,可以单实现,也可以多实现
* 并且还可以在继承一个类的同时实现多个接口
* c:接口与接口:
* 继承关系,可以单继承,也可以多继承
抽象类和接口的区别:
两者都会用到关键字abstract ,有什么区别呢
* A:成员区别
* 抽象类:
* 成员变量:可以变量,也可以常量
* 构造方法:有
* 成员方法:可以抽象,也可以非抽象
* 接口:
* 成员变量:只可以常量
* 成员方法:只可以抽象
在接口中变量和方法都作了限制
设计理念上的区别
* 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能,是为了给子类根据自身需要,重写重写抽象方法,所以抽象类是共性功能的提取
* 接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能,也就是说要扩展的时候常写一个接口,如果想要该功能就去实现这个接口
* 对事物本质的抽象用抽象类,对事物功能的扩展用接口
看看下面代码就明白了:
1 abstract class Animal { 2 private String name; 3 private int age; 4 public Animal() {} 5 public Animal(String name,int age) { 6 this.name = name; 7 this.age = age; 8 } 9 10 public void setName(String name) { 11 this.name = name; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public void setAge(int age) { 19 this.age = age; 20 } 21 22 public int getAge() { 23 return age; 24 } 25 public abstract void eat(); 26 public abstract void sleep(); 27 }
1 class Cat extends Animal { 2 public Cat() {} 3 public Cat(String name,int age) { 4 super(name,age); 5 } 6 public void eat() { 7 System.out.println("猫吃鱼"); 8 } 9 public void sleep() { 10 System.out.println("侧着睡"); 11 } 12 }
1 interface Jumping { 2 public void jump(); 3 }
1 class JumpCat extends Cat implements Jumping { 2 public JumpCat() {} 3 public JumpCat(String name,int age) { 4 super(name,age); 5 } 6 public void jump() { 7 System.out.println("猫跳高"); 8 } 9 }
1 public class Test1_Animal { 2 public static void main(String[] args) { 3 Cat c = new Cat("加菲",8); 4 c.eat(); 5 c.sleep(); 6 JumpCat jc = new JumpCat("跳高猫",3); 7 jc.eat(); 8 jc.sleep(); 9 jc.jump(); 10 } 11 }
运行结果:
猫吃鱼
侧着睡
猫吃鱼
侧着睡
猫跳高
现在看看这些面向对象中的设计,都是有道理的,都是观察现实中的事物,然后抽取出来的
为实现不同的功能而设计的
Java语言,不管是什么编程语言,这些设计者是真的厉害
以上是关于面向对象03的主要内容,如果未能解决你的问题,请参考以下文章