JAVA Day5 总结(多态,接口,内部类)

1、多态的概述

A:多态(polymorphic)概述

* 事物存在的多种形态 

B:多态前提

* a:要有继承关系。
* b:要有方法重写。
* c:要有父类引用指向子类对象。

C:多态特点

* a:对于"子类拥有" 而 "父类没有" 的方法或变量,   无法调用
* b:子类转型为父类的规则:
		1、只能调用父类的属性
		2、只能调用被子类复写的方法,,(如果子类没有复写,则去父类查询,父类如果有,则调用)

2、多态中的成员访问特点

A:成员变量

对于成员变量会显示父类的值

B:成员方法

对于成员方法会使用子类的重写方法

C:静态方法

对于静态方法会使用父类方法(对于子类的相同方法其实并不算是重写)

//对于成员变量
        System.out.println(((Son1) father1).i); //这么写,输出的是子类的 值
        System.out.println( father1.i);         //这么写,输出的是父类的 值

3、多态中向上转型和向下转型

Person p = new SuperMan();向上转型
SuperMan sm = (SuperMan)p;向下转型

3、多态的好处和弊端

A:多态的好处

* a:提高了代码的维护性(继承保证)
* b:提高了代码的扩展性(由多态保证)

B:案例演示

* 多态的好处
* 可以当作形式参数,可以接收任意子类对象

C:多态的弊端

* 不能使用子类的特有属性和行为。

4、多态的使用

//开发的是很少在创建对象的时候用父类引用指向子类对象
Animal a = new Cat();			

//当作参数的时候用多态最好,因为扩展性强
public static void method(Animal a) {	
		//关键字 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.lookHome();
		}else {
			a.eat();
		}
	}
}

5、抽象类的概述及其特点

A:抽象类概述

* 抽象就是看不懂的 

B:抽象类特点

* a:抽象类和抽象方法必须用abstract关键字修饰
	* abstract class 类名 {}
	* public abstract void eat();
* b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
* c:抽象类不能实例化那么,抽象类如何实例化呢?
	* 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
* d:抽象类的子类
	* 要么是抽象类
	* 要么重写抽象类中的所有抽象方法

6、抽象类的成员特点

A:抽象类的成员特点

* a:成员变量:既可以是变量,也可以是常量。
* b:构造方法:有。
	* 用于子类访问父类数据的初始化。
* c:成员方法:既可以是抽象的,也可以是非抽象的。
* d:abstract是否可以修饰成员变量?不能修饰成员变量

B:抽象类的成员方法特性:

* a:抽象方法 强制要求子类做的事情。
* b:非抽象方法 子类继承的事情,提高代码复用性。

7、抽象类中的面试题

A:面试题1

* 一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
* 可以
* 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成

B:面试题2

* abstract不能和哪些关键字共存
* 	abstract和static
被abstract修饰的方法没有方法体
被static修饰的可以用类名.调用,但是类名.调用抽象方法是没有意义的
abstract和final
被abstract修饰的方法强制子类重写
被final修饰的不让子类重写,所以他俩是矛盾
abstract和private
被abstract修饰的是为了让子类看到并强制重写
被private修饰不让子类访问,所以他俩是矛盾的

//public static abstract void print();		//错误: 非法的修饰符组合: abstract和static    
//public final abstract void print();		//错误: 非法的修饰符组合: abstract和final       
private abstract void print();				//错误: 非法的修饰符组合: abstract和private         

8 、接口的概述及其特点

A:接口概述

* 从狭义的角度讲就是指java中的interface
* 从广义的角度讲对外提供规则的都是接口 

B:接口特点

* a:接口用关键字interface表示	
	* interface 接口名 {}
* b:类实现接口用implements表示
	* class 类名 implements 接口名 {}
* c:接口不能实例化
	* 那么,接口如何实例化呢?
	* 按照多态的方式来实例化。
* d:接口的子类
	* a:可以是抽象类。但是意义不大。
	* b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

9、接口的成员特点

A:接口成员特点

* 成员变量;只能是常量,并且是静态的并公共的。
		* 默认修饰符:public static final
		* 建议:自己手动给出。
* 构造方法:接口没有构造方法。
* 成员方法:只能是抽象方法。
		* 默认修饰符:public abstract
		* 建议:自己手动给出。

10、类与类,类与接口,接口与接口的关系

A:类与类,类与接口,接口与接口的关系

* a:类与类:
	* 继承关系,只能单继承,可以多层继承。
* b:类与接口:
	* 实现关系,可以单实现,也可以多实现。
	* 并且还可以在继承一个类的同时实现多个接口。
* c:接口与接口:
	* 继承关系,可以单继承,也可以多继承。

11、抽象类和接口的区别

A:成员区别

* 抽象类:
	* 成员变量:可以变量,也可以常量
	* 构造方法:有
	* 成员方法:可以抽象,也可以非抽象
* 接口:
	* 成员变量:只可以常量
	* 成员方法:只可以抽象

B:关系区别

* 类与类
	* 继承,单继承
* 类与接口
	* 实现,单实现,多实现
* 接口与接口
	* 继承,单继承,多继承

C:设计理念区别

* 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
* 接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。




				本类	 同一个包下(子类和无关类)	不同包下(子类)	不同包下(无关类)
	private 	Y		
	默认		Y		        Y
	protected	Y	        	Y					 Y
	public		Y		        Y					 Y	 		        Y

12、类及其组成所使用的常见修饰符

  • A:修饰符:

    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract
  • B:类:

    • 权限修饰符:默认修饰符,public

    • 状态修饰符:final

    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • C:成员变量:

    • 权限修饰符:private,默认的,protected,public

    • 状态修饰符:static,final

    • 用的最多的就是:private

  • D:构造方法:

    • 权限修饰符:private,默认的,protected,public

    • 用的最多的就是:public

  • E:成员方法:

    • 权限修饰符:private,默认的,protected,public

    • 状态修饰符:static,final

    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • F:除此以外的组合规则:

    • 成员变量:public static final
    • 成员方法:
      • public static
      • public abstract
      • public final

13、内部类概述和访问特点

  • A:内部类概述
  • B:内部类访问特点
    • a:内部类可以直接访问外部类的成员,包括私有。
    • b:外部类要访问内部类的成员,必须创建对象。
    • 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
      (Outer.Inter obj = new Outer().new Inter()?
    • 对于静态内部类:Outer.Inter obj = new Ouer.Inter();
  • C:案例演示
    • 内部类极其访问特点
//外部类名.内部类名 = 外部类对象.内部类对象
		Outer.Inner oi = new Outer().new Inner();			//创建内部类对象
		oi.method();


class Outer {
	private int num = 10;
	class Inner {
		public void method() {
			System.out.println(num);
		}
	}
}

14、成员内部类私有使用

  • private
class Demo2_InnerClass {
	public static void main(String[] args) {
		//Outer.Inner oi = new Outer().new Inner();
		//oi.method();

		Outer o = new Outer();
		o.print();
	}
}

class Outer {
	private int num = 10;
	private class Inner {
		public void method() {
			System.out.println(num);
		}
	}

//直接返回Inner类可以, 但是什么都做不了
	public void print() {
		Inner i = new Inner();
		i.method();
	}
}

15、静态成员内部类

  • static
  • B:成员内部类被静态修饰后的访问方式是:
    • 外部类名.内部类名 对象名 = 外部类名.内部类对象;
  • 注意 静态内部类中也只能 调用 静态的方法和变量
public class Day4_Demo3 {
    public static void main(String[] args) {
        DemoClass1.Interclass ii = new DemoClass1.Interclass();
        ii.me();
    }
}


class DemoClass1{

   static int mun = 19;
    static class Interclass{
        private int num =199;
        public void me(){
            System.out.println(mun);
        }
    }
}

16、成员内部类的面试题

  • A:面试题
  •   要求:使用已知的变量,在控制台输出30,20,10。
      
      class Outer {
      	public int num = 10;
      	class Inner {
      		public int num = 20;
      		public void show() {
      			int num = 30;
      			System.out.println(?);
      			System.out.println(??);
      			System.out.println(???);
      		}
      	}
      }
      class InnerClassTest {
      	public static void main(String[] args) {
      		Outer.Inner oi = new Outer().new Inner();
      		oi.show();
      	}	
      }
    

//内部类之所以能获取到外部类的成员,是因为他能获取到外部类的引用外部类名.this
System.out.println(Outer.this.num);

17、局部内部类访问局部变量的问题

  • A:案例演示
    • 局部内部类访问局部变量必须用final修饰

    • 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
      因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用

      jdk1.8可以使用任意变量

18、匿名内部类的格式和理解

  • A:匿名内部类
    • 就是内部类的简化写法。
  • B:前提:存在一个类或者接口
    • 这里的类可以是具体类也可以是抽象类。
  • C:格式:
  •   new 类名或者接口名(){
      	重写方法;
      }
    
  • D:本质是什么呢?
    • 是一个继承了该类或者实现了该接口的子类匿名对象。
  • E:案例演示
    • 按照要求来一个匿名内部类
public class Day4_Demo5 {
    public static void main(String[] args) {
        new InterFace1(){
            @Override
            public void me() {
                System.out.println(i);
            }
        }.me();
    }
}

interface InterFace1{
    public static final int i = 0;

    public void me();
}



  • 小结:
    1. 若在类中实现需要在方法中实现
    2. 匿名内部类只针对重写一个方法时候使用
    3. 在定义后需要自己在进行调用,否则不起作用
    4. 匿名内部类是不能向下转型的,因为没有子类类名
abstract class Person {
    public abstract void show();
}
class PersonDemo {

//若在类中实现需要在方法中实现	
public void one(){
    new Person(){
       //匿名内部类只针对重写一个方法时候使用
        @Override
        public void show() {
            System.out.println(1);
        }
    }.show();  	//在定义后需要自己在进行调用,否则不起作用

19、匿名内部类重写多个方法调用

  • A:案例演示
    • 匿名内部类的方法调用

20、匿名内部类在开发中的应用

class Test1_NoNameInnerClass {
	public static void main(String[] args) {
		//如何调用PersonDemo中的method方法呢?
		PersonDemo pd = new PersonDemo ();
		//pd.method(new Student());
		pd.method(new Person() {
			public void show() {
				System.out.println("show");
			}
		});//这里不写.show  的原因是在下面method 中已经调用了             
	}
}
//这里写抽象类,接口都行
abstract class Person {
	public abstract void show();
}              
class PersonDemo {
		public void method(Person p) {
		p.show();
	}
}

21、匿名内部类的面试题

  • A:面试题
  •   按照要求,补齐代码
      interface Inter { void show(); }
      class Outer { //补齐代码 }
      class OuterDemo {
      	public static void main(String[] args) {
      		  Outer.method().show();
      	  }
      }
      要求在控制台输出”HelloWorld”
    
  •   1. 静态方法的调用需要类名.方法()   因此method 需要静态
    
  •   2. 而只有new Inter(){....} 才能调用show方法   因此返回的需要是整个匿名对象(直接返回Inter即可,父类引用指向子类对象)
    
interface Inter {
    void show();
}

class Outer { //补齐代码
    public static Inter method() {
   return  new Inter(){
            @Override
            public void show() {
                System.out.println("小王八");
            }
        };
    }
}

class OuterDemo {
    public static void main(String[] args) {
        Outer.method().show();
        //静态方法的调用需要类名.方法()   因此method 需要静态
        //而只有new Inter(){....} 才能调用show方法   因此返回的需要是整个匿名对象(直接返回Inter即可,父类引用指向子类对象)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值