一.多态
1.前提条件:
(1) 必须有继承关系
(2) 必须有方法重写(子类出现父类一样的方法声明)
(3) 必须有父类引用指向子类对象(向上转型) eg: Fu f = new Zi ( );
2.成员访问特点
(1)成员变量: 编译看左,运行看左
(2)成员方法:(非静态) 编译看左,运行看右
(静态)【算不上方法重写】 编译看左,运行看左
(3)构造方法: alt + shift + s + c 无参构造
alt + shift + s + c 有参构造
alt + shift + s + r set/get 方法
3.好处
(1) 提高代码维护性(继承保证)
(2) 提高代码扩展性(多态保证)
4
.弊端
不能访问子类特有功能 eg: 猫的 playGame
解决弊端:
(1)创建子类具体对象 eg: Cat c = new Cat( ); 耗费内存,浪费空间
(2)向下转型: 将父类的引用强制转换为子类的引用 (前提是必须有父类的引用存在)
向下转型必须依赖于向上转型
eg: Cat c = (Cat) a ;
c.playGame( );
向下转型异常问题:
eg: 运行时期异常 ClassCastException 类转换异常
//内存是狗
Animal4 a = new Dog4() ;
//向下转型:还原成狗
Dog4 d = (Dog4)a ;
//内存是猫
a = new Cat4() ;
//还原成猫
Cat4 c = (Cat4) a ;
//编译通过了
Dog4 dd = (Dog4)a ; //不能将内存猫转换为狗
示例代码1:
package org.lemon.多态;
//定义动物类
class Animal{
public void eat() {
System.out.println("eat...");
}
public void sleep() {
System.out.println("sleep...");
}
}
//定义子类
class Cat extends Animal{
//方法重写
public void eat() {
System.out.println("猫吃鱼...");
}
public void sleep(){
System.out.println("猫趴着睡...");
}
}
//定义子类
class Dog extends Animal{
//方法重写
public void eat() {
System.out.println("狗吃骨头...");
}
public void sleep() {
System.out.println("狗躺着睡...");
}
}
//定义动物工具类
class AnimalTool{
public void useAnimal(Animal a) {
a.eat();
a.sleep();
}
}
//测试类
public class DuotaiDemo {
public static void main(String[] args) {
//a.eat();
//a.sleep();
//Cat c = new Cat();
//Dog d = new Dog();
Cat c = new Cat();
Dog d = new Dog();
AnimalTool at = new AnimalTool();
at.useAnimal(c);
at.useAnimal(d);
}
}
示例代码2.
package org.lemon.多态;
//定义动物类
class Animal1{
public void eat() {
System.out.println("eat...");
}
public void sleep() {
System.out.println("sleep...");
}
}
//定义子类
class Dog1 extends Animal1{
//方法重写
public void eat() {
System.out.println("狗吃骨头...");
}
public void sleep() {
System.out.println("狗躺着睡...");
}
public void shout() {
System.out.println("狗汪汪叫...");
}
}
//测试类
public class DuotaiDomo2 {
public static void main(String[] args) {
//向上转型
Animal1 a = new Dog1();
a.eat();
a.sleep();
//向下转型
Dog1 d = (Dog1) a;
d.shout();
}
}
二.抽象类(abstract)
行为功能不同,如 动物 就不能把动物定义为一个具体类。
1. 抽象类不能实例化:(不能创建对象)
引入抽象类多态(父类指向子类(具体类)引用对象,通过子类进行初始化)
2. 成员访问特点:
(1)成员变量: 变量,自定义常量 均可
eg: private String name; private int age ;
(2)构造方法: (无参构造&有参构造)
eg: public Fu(){ public Fu (String name){
} this name = name;
}
(3)成员方法: 抽象方法& 非抽象方法 均可
抽象方法:没有方法体的一个方法
eg: public abstract void show();
抽象类:
eg: abstract class Animal{
}
3.注意事项
abstract 不能和 private final static 共同使用
eg: private abstract void function ( );
public final(static) abstract void function( ) ;
示例代码:
package org.lemon.抽象类;
//定义抽象类
abstract class Animal{
//抽象方法
public abstract void eat();
public abstract void sleep();
}
//子类是具体类
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼...");
}
public void sleep() {
System.out.println("猫趴着睡...");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗吃骨头...");
}
public void sleep() {
System.out.println("狗睡觉...");
}
}
//测试类
public class AbstractDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.eat();
a.sleep();
Animal a1 = new Dog();
a1.eat();
a1.sleep();
}
}
三.接口(interface)
1. 体现出一种扩展功能 eg: 猫可以跳高
结构: interface 接口名 {
}
2. 注意事项:
接口中只能是抽象方法,且不能有构造方法;
与抽象类相同,接口不能实例化,需通过子实现类 进行初始化 !!!!
子类定义格式:
class 子实现类名 implements 接口名 {
}
eg: Jump j = new Cat ( ) ;
j. jump( ) ;
3.成员特点
(1)成员变量: 只能是常量 且存在默认修饰符 public static final
(2)成员方法: 存在默认修饰符 public abstract
(3)构造方法: 无...........
4.各种关系
(1) 类与类 (继承:extends 且java 单继承 多继承!!!!!! 可多层继承)
(2) 类与接口: 实现关系:implements (一个类继承另一个类,可实现多个接口)
eg: class 子实现名 extends Object implements 接口1,接口2;
(3) 接口与接口: 继承关系(extends) 可单继承 也可多继承
eg: interface Zi extends Inter {
}
interface Son extends Inter1,inter2{
}
5.形式参数
(1)基本数据类型: 形式参数的改变对实际参数没影响
(2)引用类型:
具体类: 需要创建该类对象 eg: Student s = new Student ( );
public void method(Student s){
}
抽象类:需要自定义抽象类的子类来实例化(抽象类多态!!!!)
(3)接口: 自定义一个子实现类,通过接口多态实例化!
6.返回值
抽象类(需要的返回值是该抽象类的子类对象!) eg: return new Teacher();
接口:需要的是返回该接口的子实现类对象
示例代码1:
package org.lemon.返回值;
//返回值是抽象类
abstract class Person{
public abstract void show();
}
//定义一个类
class PersonDemo{
public Person method() {
return new Student();
}
//定义抽象类子类
class Student extends Person{
public void show() {
System.out.println("我爱你...");
}
}
}
//测试类
public class Abstract {
public static void main(String[] args) {
PersonDemo pd = new PersonDemo();
Person p = pd.method();
p.show();
}
}
package org.lemon.返回值;
//返回值 是接口
interface Love{
public abstract void love();
}
//定义一个类
class TeacherDemo{
public Love method() {
return new Teacher();
}
}
//定义一个子实现类
class Teacher implements Love{
public void love() {
System.out.println("哎哎哎");
}
}
public class Interface {
public static void main(String[] args) {
TeacherDemo td = new TeacherDemo();
Love l = td.method();
l.love();
}
}
四.内部类 : 在一个类中定义另一个类
1. 特点 : 内部类可直接访问外部类成员,且包括私有;
而外部类访问内部类成员必须通过创建内部类的对象访问该内部类的成员。
2.内部类分类:
(1)成员内部类: 在外部类的成员位置定义
(2)局部内部类: 在外部类的局部位置定义
测试类访问成员内部类的成员方法:
非静态: eg: 外部类名 . 内部类名 对象名 = 外部类名 . 内部类对象
静态: eg: 外部类名 . 内部类名 对象名 = new 外部类名 . 内部类名();
修饰符: private 保证安全性 static :如果内部类被static 修饰,要访问外部类成员变量,必须被static修饰
对于静态内部类,无论成员方法是静态还是非静态,要访问外部类成员变量必须被static 修饰
局部内部类: 测试类访问 需创建外部类对象,使用外部类对象调用外部类成员方法
局部内部类访问局部变量: 必须用 final 修饰 变为常量永远固定
3.匿名内部类:
(必须存在一个接口或一个类)
格式: new 接口名或类名 (){
@Override
}
实质: 继承了该类(抽象类)或者实现了该接口的子类对象!