java day08_day09基础梳理

day08
一.多态

   1 .多态的概念:多态是一个事物在不同时刻体现出来的不同状态。例如:水有三种状态:固态、气态、液态。


   2.多态的三个前提条件:
    (1)必须有继承关系(没有继承关系的话,谈不上多态)
    (2)必须有方法重写(子类出现了父类一样的方法声明)
    (3)父类引用指向子类对象:向上转型。例如:Fu f=new Zi();
     这三个条件缺一不可!


   3.多态的成员访问特点:
     成员变量:编译看左,运行看左。
     非静态成员方法:编译看左,运行看右。由于存在方法重写,所以就运行最终的是子类的成员方法。
     静态成员方法:编译看左,运行看左。

     构造方法:还是对象进行初始化,由于是一种继承方法,还是分层初始化。

成员访问的例子:

class Fu{
	public int num = 10 ;
	
	//父类的成员方法
	public void show(){
		System.out.println("show Fu...");
	}
	
	//静态方法
	public static void function(){
		System.out.println("function Fu....");
	}
}
//子类
class Zi extends Fu{
	int num = 20 ;
	
	public void show(){
		System.out.println("show Zi...");
	}
	
	public static void function(){
		System.out.println("function Zi....");
	}
}

//测试类
public class DuoTaiDemo {
	public static void main(String[] args) {
		//创建父类的对象:多态的形式
//		有父类引用指向子类对象:向上转型
		Fu f = new Zi() ;
		//访问成变量:编译看左,运行看左
		System.out.println(f.num);//10
		
		//调用成员方法:show() 编译看左,运行看右
		f.show() ;//show Zi...
		
		//静态方法编译看做,运行看左
		f.function() ;//function Fu....
	}
}




   4.多态的优点:
     (1)可以提高代码的维护性(由继承保证)
     (2)可以提高代码的扩展性(由多态保证)
    
   5.多态的弊端:不能访问子类的特有功能。
     解决方法:(1)创建子类的具体对象,来访问自己的特有功能。虽然可以解决多态弊端,但是从内存角度考虑,
                    要创建子类对象,那么必须在堆内存开辟空间,浪费空间。


                    创建子类的具体对象时可能出现的异常:OOM异常;Out Of Memory严重异常:内存溢出。


               (2)多态的第三个前提条件是,父类引用指向子类对象,那么,可不可以将子类的引用指向父类的
                    对象呢?答案是可以的。向下转型就是将父类的引用强制转换为子类的引用,前提是必须有父
                    类的引用存在。向下转型必须依赖于向上转型。
                    
                    向下转型可能出现的异常:Class Cast Exception  类转换异常
                                            ArrayIndexOutOfBoundsException 数组角标越界异常
                                            Null Pointer Exception:空指针异常(解决方案:给对象做非空判断)
                                            if(对象名!=null){
                                            给对象进行操作
                                            }


访问子类特有功能的例子:

package example;

class Animal2{
	public void show(){
		System.out.println("show Animal2...");
	}
}

//子类
class Cat2 extends Animal2{
	public void show(){
		System.out.println("show Cat2....");
	}
	
	//特有功能
	public void playGame(){
		System.out.println("猫玩毛线...");
	}
}
//测试类
public class DuoTaiDemo3 {
	public static void main(String[] args) {
		//多态的形式:父类引用指向子类对象
		Animal2 a = new Cat2() ;
		a.show() ;
		Cat2 b=(Cat2)a;
		b.playGame();
//	a.playGame() ;
	}
}








二.抽象类
   1.概念:每一个动物的吃和睡的功能不一样,不应该把动物类定义为一个具体类,而是给出一个声明。
           当一个类中如果有抽象功能(抽象方法)的时候,那么这个类一定要定义为抽象类。


   2.抽象方法:没有方法体的一个方法。例如:public abstract void eat();


     问题:一个抽象类中可以有非抽象方法吗:
     答案:一个抽象类中可以有抽象方法,也可以有非抽象方法。
 
  3.抽象类的实例化:
    抽象类不能实例化,抽象类不能创建对象

    一个抽象类如何进行实例化:通过抽象类多态形式:父类的引用指向子类对象,通过子类进行初始化。

抽象类实例化的例子:

abstract class Animal{
	
	//抽象方法:没有方法体的一个方法
	public abstract void eat() ;
	
	public abstract void sleep() ;
	
	//具体方法
	/*public void eat(){
		System.out.println("eat");
	}*/
	
	public void show(){
		System.out.println("show Animal....");
	}
}

//抽象的子类
//abstract class Cat extends Animal{
//	
//}
//子类是具体类
class Cat extends Animal{

	@Override
	public void eat() {
		System.out.println("猫吃鱼");
	}

	@Override
	public void sleep() {
		System.out.println("猫趴着睡觉..");
	}
	
}

//测试类
public class AbstractDemo {
	public static void main(String[] args) {
		//当前Animal已经被abstract修饰了
//		Animal a = new Animal();//Cannot instantiate the type Animal:抽象类不能实例化:instaceof
		
		//多态:父类引用指向子类对象
		Animal a = new Cat() ; //Animal是抽象类,---->抽象类多态形式
		a.eat() ;
		a.sleep() ;
	}
}




  4.抽象类子类的特点:
    如果抽象类的子类也是抽象类,那么这个子类就没有意义。
    因为抽象类最终使用的就是通过子类进行对象的初始化,如果子类被抽象修饰了,那么也不能创建对象,
    没有意义。
  
  5.抽象类的成员特点
    成员变量:可以是变量,也可以是自定义常量。
    构造方法:抽象类可以有构造方法:包括有参构造和无参构造。
    构造方法的作用:通过抽象类多态的形式,让子类进行数据初始化
    成员方法:可以有抽象方法,也可以有非抽象方法。


  6.抽象类的成员方法特性:
    抽象方法:强制子类必须做一件事情:方法重写;
    非抽象方法:由继承保证可以提高代码的复用性。


    问题:一个类中如果没有抽象方法,那么这个类可不可以定义为一个抽象类呢?

    答案:可以。定义为抽象类,不能让其创建对象。


例子:

abstract class Fu{
	
	private String name ;
	private int age ;
	//成员变量
	public int num = 100 ;
	public final int num2 = 200 ; //被final修饰:自定义常量
	
	//无参构造
	public Fu(){
		
	}
	
	//有参构造
	public Fu(String name,int age){
		this.name = name ;
		this.age = age ;
	}
	
	//抽象方法
	public abstract void show();
	
	//非抽象方法
	public void function(){
		System.out.println("function Fu...");
	}
	
}

//子类
class Zi extends Fu{
	
	@Override
	public void show(){
		System.out.println("show Zi....");
	}
	
}
//测试类
public class AbstractDemo2 {
	public static void main(String[] args) {
		//抽象类多态:
		//抽象类的类名 对象名= new 子类名() ;
		Fu f = new Zi() ;
		f.show() ;
		f.function() ;
	}
}




三.接口
   
    1.概念:接口体现的是一种扩展功能。比如:猫可以跳高(并不是所有的猫都可以)
           interface 接口名{
           }


     问题:接口里面的方法可以是非抽象方法吗?
     答案:不可以,只能是抽象方法。




   2.接口的特点: 
     (1)不能实例化(不能直接创建对象)
     (2)接口中不能有构造方法


   3.接口如何实例化:
     (1)接口的子实现类:
          a.接口的子实现类是抽象类,没有意义。实际开发中用的就是
          b.接口的子实现类是非抽象类
     (2)接口的实例化:就是通过子实现类对数据进行初始化
          格式: class 子实现类名 implements(实现) 接口名{
                 }


   4.接口成员的特点:
      (1)成员变量:只能是常量,存在默认修饰符:public static final.
      (2)构造方法:接口没有构造方法的。
      (3)成员方法:接口中的成员方法默认修饰符 public abstract.


接口的例子1:

//定义跳高的接口
interface Jump{
	
	//非抽象方法:抽象类中不能有抽象方法
//	public void jump(){
//		System.out.println("猫可以跳高了...");
//	}
	
	public abstract  void  jump() ;
	
	//构造方法:不能有
//	public Jump(){
//		
//	}
}

//子实现类是抽象类类
//abstract class Cat implements Jump{
//子实现类是非抽象类
class Cat implements Jump{

	@Override
	public void jump() {
		System.out.println("猫可以跳高了...");
	}
	
}

//测试类
public class InterfaceDemo {
	public static void main(String[] args) {
		//创建接口对象
//		Jump j = new Jump() ;//接口不能实例化
		
		//接口多态:接口的引用指向子实现类对象
		Jump j = new Cat() ;
		j.jump();
	}
}

接口的例子2:

//定义一个接口
interface Inter{
	public static final int num = 100 ;
	public static final  int num2 = 200 ;
	//抽象方法
	
	//全部给出默认修饰符
	public abstract void show() ;
	
	//接口没有构造方法
//	public Inter(){
//		
//	}
	
	public abstract void function() ;
}

//定义接口的子实现类:见名知意:接口名+impl
class InterImpl implements Inter{
	
	@Override
	public void show() {
		System.out.println(num);
		System.out.println(num2);
	}

	@Override
	public void function() {
		System.out.println("function InterImpl...");
	}
	
}

//测试类
public class InterfaceDemo2 {
	public static void main(String[] args) {
		//创建接口对象:接口多态的形式
		Inter i = new InterImpl() ;
//		i.num = 20 ;//当前num变量:被final修饰
		System.out.println(Inter.num);//接口名.成员变量(当前变量被static修饰)100
		System.out.println(Inter.num2);//200
		System.out.println("-------------");
		i.show() ;//100
		i.function() ;//200
	}
}





     面试题:接口和抽象类的区别
     (1)成员的区别:
          a.成员变量:
            抽象类:成员变量可以是常量,也可以是变量;
            接口:成员变量只能是一种常量,存在默认修饰符: public static final;
          b.构造方法:
            抽象类:可以有无参、有参构造方法
                     作用:通过子类进行数据初始化
            接口:无构造方法
          c.成员方法:
            抽象类:可以有抽象方法,也可以有非抽象方法。
            接口:只能有抽象方法,存在默认修饰符:public abstract;
      (2)关系的区别:
           a.类与类的关系:继承关系extends。java中只支持单继承,不支持多继承,可以实现多层继承。
           b.类与接口的关系:实现关系implements。并且,一个类继承另一个类的同时,可以实现多个接口。
               例如:class 子实现类名 extends Object implements 接口名1,接口名2{
                      }
           
           c.接口与接口的关系:继承关系extend。可以支持单继承,也可以支持多继承。
     (3)设计理念的区别
           抽象类:体现的是一种“is a”的关系,存在继承关系。
           接口:体现的是一种“like a”的关系,由于接口的扩展功能。
作业:


1:教练和运动员案例(学生分析然后讲解)
乒乓球运动员和篮球运动员。
乒乓球教练和篮球教练。
为了出国交流,跟乒乓球相关的人员都需要学习英语。
请用所学知识:
分析,这个案例中有哪些抽象类,哪些接口,哪些具体类


抽象类有:运动员类、教练类、人类
接口:    学习英语
具体类:乒乓球运动员类、篮球运动员类、乒乓球教练类、篮球教练类




2:final关键字可以干什么?有什么特点?
   final可以修饰类,修饰成员方法和变量。
   final修饰类,该类不能继承;
   final修饰成员方法,该方法不能被重写;
   final修饰变量,例如:final int x=10;该变量是一个常量(自定义常量);
   final修饰局部变量:
        (1)基本数据类型:如果局部变量是一个基本数据类型,那么被final修饰,基本数据类型的变量的值不能再改变;
        (2)引用数据类型:如果用final修饰的引用类型的变量,那么它不能再重写分配堆内存空间,但是可以改变成员变量的值。
   


3:final关键字的面试题?
A:修饰局部变量
          final修饰局部变量:
        (1)基本数据类型:如果局部变量是一个基本数据类型,那么被final修饰,基本数据类型的变量的值不能再改变;
        (2)引用数据类型:如果用final修饰的引用类型的变量,那么它不能再重写分配堆内存空间,但是可以改变成员变量的值。
B:初始化时机
          在对象创建之前都可以进行初始化
          (1)构造代码块中可以进行初始化;
          (2)构造方法中可以进行初始化;
          (3)定义成员变量的时候,可以直接进行初始化。



4:多态是什么,前提是什么?
  多态是指一个事物在不同时刻体现出来的不同状态。
  多态的前提:
       (1)必须有继承关系
       (2)必须有方法重写
       (3)有父类引用指向子类对象(向上转型)
       


5:多态中成员访问的特点?
成员变量:编译看左,执行看左
成员方法:编译看左,运行看右,由于存在方法重写,所以运行最终的是子类的成员方法。
静态方法:编译看左,运行看左


6:多态的好处及弊端?如何解决多态的弊端?
   多态的好处:
        (1)可以提高代码的维护性(由继承保证)
        (2)可以提高代码的扩展性(由多态保证)
   多态的弊端:不能访问子类的特有功能
   解决弊端方法:
        (1)创建子类的具体对象,来访问自己的特有功能,虽然可以解决多态弊端,但是从内存角度考虑。
             要创建子类对象,必须在堆内存开辟空间,浪费空间。
        (2)既然多态的第三个前提条件:父类引用指向子类对象,那么我们也可以将子类的引用指向父类的对象,
             即将父类的引用强制转换为子类的引用,前提是必须有父类的引用存在。


7:什么是向上转型?什么是向下转型?
    向上转型:父类引用指向子类对象
    向下转型:将父类的引用强制转换为子类的引用



8:抽象类概述及其特点?
  抽象类的概述:当一个类中如果有抽象方法的时候,那么这个类就应该定义为一个抽象类。
  抽象类的特点:抽象类不能实例化
   


9:抽象类成员特点?
  成员变量:可以是变量,也可以是自定义常量
  构造方法:抽象类可以有构造方法:包括有参构造和无参构造。
            作用:通过抽象类多态的形式,让子类进行数据初始化
  成员方法:可以有抽象方法,也可以有非抽象方法。




10:抽象类的小问题
A:一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
          可以。意义:不能让其创建对象。
B:abstract不能和哪些关键字共存
          abstract不能和private、final、static共同使用


11:接口的概述及其特点?
        接口的概述:接口体现的是一种扩展功能。如:猫可以跳高(并不是所有的猫都可以)
        接口的特点:不能实例化(不能直接创建对象)


12:接口的成员特点?
       成员变量:只能是常量,存在默认修饰符:public static final
       构造方法:接口是,没有构造方法的。
       成员方法:接口中的成员方法默认修饰符public abstract


13:抽象类和接口的区别?
    成员的区别:
    (1)成员变量:
         抽象类:成员变量可以是常量,也可以是变量。
         接口:成员变量只能是一种常量:存在默认修饰符:public static final
    (2)构造方法:
         抽象类:可以有无参、有参构造方法
         接口:没有构造方法
    (3)成员方法:
         抽象类:可以有抽象方法,也可以有非抽象方法
         接口:只能是抽象方法,存在默认修饰:public abstract
   关系的区别:
    (1)类与类的关系:继承关系extends
    (2)类与接口的关系:实现关系implements,并且一个类继承另一个类的同时,可以实现多个接口
    (3)接口与接口的关系:继承关系,可以支持单继承,也可以支持多继承


day09
一.形式参数和返回值问题
    1.形式参数:
       (1)基本数据类型:你要什么数据类型,在实际传参的时候就传什么数据类型。形式参数的改变
            对实际参数没有影响。
       (2)引用数据类型:需要创建该类的对象
            a.具体类:如果形式参数是一个具体类,那么需要创建该类对象。
            b.抽象类:如果形式参数是一个抽象类,需要自定义一个子类,来进行实例化。

            c.接口:如果形式参数是一个接口,需要定义一个接口的子实现类,通过接口多态的形式给接口实例化。

形式参数是抽象类的例子:

//声明一个抽象类
abstract class Person{
	public abstract void study() ;
	
}

//定义一个PersonDemo类
class PersonDemo{
	//成员方法
	public void method(Person p){//Person p = new Perosn();//错误的:抽象类不能实例化---->抽象类的多态:Person p = new Student2() ;
		p.study() ;
	}
}

//自定义一个抽象的子类来进行Person的实例化
class Student2 extends Person{

	@Override
	public void study() {
		System.out.println("good good study ,day day up!");
	}
	
}

//测试类
public class PersonTest {
	public static void main(String[] args) {
		//需求:调用PersonDemo类中method()方法
		//创建PersonDemo类的对象
//		PersonDemo pd = new PersonDemo() ;
		pd.method(p) ;
//		//需要使用抽象类多态来实例化
//		Person  p = new Student2() ;
//		pd.method(p) ;
		
		//链式编程:
		new PersonDemo().method(new Student2()) ;
	}
}


    2.返回值: 
        a.具体类:直接返回该类对象(通常实际开发中使用的是匿名对象)
        b.抽象类:返回值如果是抽象类,需要返回的是该抽象类的子类对象。
        c.接口:返回值如果是接口类型,需要返回的是该接口的子类实现对象。


二.内部类
   1.定义:在一个类中定义另一个类,那么把这种情况称为内部类。
           举例:在A中定义一个类B,类B就是类A的内部类,同理,类A就是类B的外部类。
           内部类可以直接访问外部类的成员,包括私有。

           外部类想要访问内部类的成员,必须通过创建内部类的对象访问。

内部类例子:

class Outer7 {
	public int num = 10;
	
	class Inner7 {
		public int num = 20;
		public void show() {
			int num = 30;
			System.out.println(num);
			System.out.println(this.num);
			System.out.println(new Outer7().num);//要访问外部类的成员变量:匿名对象 :
                                                              //  new 外部类名().成员变量
			//外部类的this限定
			System.out.println(Outer7.this.num);
			
		}
	}
}
public class InnerClassTest {
	public static void main(String[] args) {
		Outer7.Inner7 oi = new Outer7().new Inner7();
		oi.show();
	}
}


  
   2.内部类的分类:
       成员内部类:在外部类的成员位置。
       局部内部类:在外部类的局部位置定义的这个类。


   3.成员内部类:
      a. 在测试类中,调用成员内部类的方法:
        外部类名.内部类名 对象名=外部类对象.内部类对象
      b.成员内部类的修饰符:
        private:为了保证数据的安全性
        static:为了方便调用
               如果成员内部类static修饰,那么要访问外部类的成员变量,这个变量必须被static修饰。
        静态的成员内部类访问该类中的成员方法的格式:
          外部类名.内部类名 对象名=new 外部类名.内部类名().
  
       结论:对于静态的成员内部类来说,无论静态成员内部类中的成员方法是静态的还是非静态的,要访
             问外部类的成员变量,该变量必须被static修饰。


     
   4.局部内部类:定义在外部类的局部位置
       

     结论:无论是局部内部类还是非静态的成员内部类 ,都可以直接访问外部类的成员,包括私有。

例子:

//外部类
class Outer3{
	//定义外部类的变量
	public int num  = 10 ;
	
	//成员内部类(非静态成员内部类)
	class Inner3{
		//内部类的成员方法(非静态的成员方法)
		public void show(){
			System.out.println(num);
		}
	}
	
	/*public void method(){
		Inner3 i = new Inner3() ;
		i.show() ;
	}*/
	
}

//测试类
public class InnerDemo3 {
	public static void main(String[] args) {
		/**
		 * 需求:现在需要访问Inner3成员内部类中的show()方法
		 * */
//		Inner3 i = new Inner3() ; //Inner3是一个成员内部类
//		外部类名.内部类名 对象名 = 外部类对象.内部类对象;
		
		Outer3.Inner3 oi = new Outer3().new Inner3() ;
		//使用对象名调用show()方法
		oi.show() ;
	}
}






   面试题:局部内部类访问局部变量为什么会出现问题?
           当前局部变量报错,必须用final修饰,为什么要用final修饰?
           因为局部变量时随着方法调用而生成的,随着方法的调用完毕而消失,而现在局部位置有一个局
           部内部类,它要在自己的成员方法位置访问当前的局部变量,必须把变量变成一个常量,要用final,
           这样的一个值永远是固定的。


   5.匿名内部类:是内部类的简化版格式
    (1) 前提条件:必须存在一个接口或者是一个类(可以是具体类,也可以是一个抽象类)
    (2)书写格式:  new 接口名或者类名(){
                方法重写;
                 }

    (3)匿名内部类的实质:继承了该类(抽象类)或者是实现了该接口的子类对象。

6.如何使用API

   (1)打开API:
显示---->输入你查找的类
索引---->搜索

  (2)找到某一个类:
对该类的描述
看类结构:
看该类是否有字段(变量),构造方法(如何创建该类对象),方法(类的成员方法)
出现该类的版本号:


          Scanner java.util.Scanner;

          JDK5.0以后的新特性:自动拆装箱(int--->Integer,char--->Character),静态导入(导入的方法级别),可变参数,增强              for循环(集合),枚举
         JDK7.0也有新特性(匿名内部类:局部内部类访问局部变量特性:局部变量必须被final讲)

写API的书写格式的例子:

package org.westos.版本2;
/**
 * 
 * 该类是针对数组操作的一个工具类,里面有一些对数组操作的功能
 * @author Apple
 * @version V1.0
 * */
public class ArrayTool {
	//无参构造私有,目的为了不让外界其对象
	private ArrayTool(){
		
	}
	
	/**
	 * 该方法是针对数组的遍历的方法,遍历的元素[元素1, 元素2, 元素, ....]
	 * @param   arr :需要被遍历的数组
	 * */
	public static void printArray(int[] arr){
		System.out.print("[");
		for(int x = 0 ; x < arr.length ; x ++){
			if(x==arr.length-1){
				System.out.println(arr[x]+"]");
			}else{
				System.out.print(arr[x]+", ");
			}
		}
	}
	/**
	 * 该方法是针对数组获取最大值的方法
	 * @param  arr :需要被遍历的 数组,可以获取每一个元素
	 * @return 返回的就是数组中最大值
	 * 
	 * */
	public static int getMax(int[] arr){
		//定义参照物
		int max = arr[0] ;
		//遍历其他索引
		for(int x = 1 ; x < arr.length ;x ++){
			//判断
			if(arr[x]>max){
				max = arr[x] ;
			}
		}
		
		return max ;
	}
	
	/**
	 * 该方法是查询数组中的元素在数组中第一次出现的索引
	 * @param    arr : 需要查询的数组
	 * @param	 value:需要被查找的远古时
	 * @return 	如果查到了当前索引对应的元素,那么就直接返回当前索引,如果查不到,则返回-1
	 * */
	public static int getIndex(int[] arr,int value){
		//假设法
		//定义一个索引:假设查不到
		int index = -1 ;
		
		//遍历数组
		for(int x = 0 ; x < arr.length ; x ++){
			//判断:如果刚好查到的x索引对应的元素和value相等,那么返回该索引
			if(arr[x]==value){
				//表查到了
				//给索引遍历重新赋值
				index  = x ;
				break ;
			}
		}
		return index ;
		
		
	}
}








作业:
1:博客自己总结这两天学的东西
2:形式参数和返回值问题
形式参数
基本类型:你要什么数据类型,在实际传参的时候就传什么数据类型。形式参数的改变对实际参数没有影响
引用类型:需要创建该类的对象
                          具体类:形参是具体类,需要创建该类对象
                          抽象类:形参是抽象类,需自定义一个子类,来进行实例化
                接口:如果形参是接口,需自定义一个接口的子实现类,通过接口多态的形式给接口进行实例化
返回值类型
基本类型
引用类型:
                        具体类:直接返回该类对象
                        抽象类:需要返回该抽象类的子类对象
                        接口:返回该接口的子类实现对象


3:内部类的概述及访问特点
  内部类的概述:在一个类中定义另一个类,那么把这种情况称为内部类
  访问特点:内部类是可以直接访问外部类的成员,包括私有。
            外部类想要访问内部类的成员,必须通过创建内部类的对象访问。


4:内部类的分类
  成员内部类:在外部类的成员位置
  局部内部类:在外部类的局部位置定义的这个类。
5:匿名内部类的格式和应用及面试题
  匿名内部类的格式: 
  new 接口名或者类名(){
    方法重写;
  }


下去复习:常用类:
Object类,String类,StringBuffer类



   
    
     
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值