疯狂Java学习笔记(010)

回顾 前一天的内容

一、实例变量和局部变量的区别

1. 定义位置和作用范围

  实例变量,定义在类中,作用范围是整个类;

  局部变量,定义在局部范围内,作用范围是方法内、形参上、代码块;

2. 生命周期

  实例变量,随着对象的创建而存在,随着对象消失;

  局部变量,方法或语句执行完,变量空间自动释放;

3. 存在的内存位置

  实例变量,存在于对象所在的堆内存中;

  局部变量,存在于栈内存中;

4. 是否有初始值

  实例变量,默认初始值是(0/0.0/false/null);

  局部变量,没有初始化值,除了形参,使用前必须赋值;

二、实例变量和静态变量的区别

1. 所属不同

  实例变量,属于对象,也称对象(实例变量);

  静态变量,属于类,也称类变量;

2. 在内存中位置不同

  实例变量,堆内存;

  静态变量,方法区;

3. 生命周期

  实例变量,随着对象的创建而存在,随着对象消失;

  静态变量,随着类的加载而加载,随着类的消失而消失;

4. 调用方法不同

  实例变量,只能使用对象名+“. ”的方法调用;

  静态变量,可以通过类名+“. ”和对象名+“. ”两种方式调动,推荐使用类名调用;

三、自定义类型当成方法的形参类型

匿名对象的使用:

  1>某个对象的方法只能调用一次,没必要起名

  2>某个对象是当成参数传给方法

class Student{
    ...
}

class Test{
    public void test(Student s){
        //这里就可以使用s指向的对象的成员了
    }
}

public class StudentTest{
    public static void main(String[] args){
        /*
        Test t = new Test();
        Student s = new Student();
        t.test(s);
        */
        //
        new Test().test(new Student());
    }
}

 

题目:自定义类型当成方法的返回值类型:

在方法中返回一个自定义类型的对象:

class A{
    
}
class Test{
    public A getA(){
        A a = new A();
        return a;
        //return new A();可以直接返回自定义类型的对象,而代替上面两句。
        
    }
}

四、面向对象的三大特点之一

包括:封装、继承、多态

  封装:private 关键字

  隐藏一些不想让外界看到的细节。

private常用方法:

  1.private 修饰成员变量,并提供对应的公共的getXxx/setXxx方法,比如 private int at;获取方法写成setAt/getAt,这种写法是固定的,在eclipse里会自动生成。

  2.private修饰的成员方法,一般都是被一个公共的方法调用,外界可以调用公共方法,

  3.private修饰构造方法,让外界不能随便创建对象。

this关键字使用场景:

  1.setXxx方法中用于区分局部变量和成员变量,

  2.构造方法中调用本类的其他构造方法(this(xxx))

  3.成员方法中调用本类的其它成员方法(this.方法(xxx))

    题目:this关键字是否可以用来给变量赋值?

class A{
    public void test(){
    A a;
    a = this; //把当前对象的引用赋值给局部变量a
    }
}

    题目:this关键字是否可以作为方法的返回值类型?

class A{    
    public A test(){
    return this;        
}

    题目:this关键字是否能作为方法的实参?

class A{
    public A test(){
        test2(this);
    }
public void test2(A a){ } }

 五、构造方法/构造子/构造器:constructor

  主要目的:

  1.给成员变量赋值,即对象初始化

  2.把当前正在构造的对象地址返回

  格式:

  1. 与类同名,没有返回值

  2. 多个构造方法是以重载的形式存在的

  3. 构造方法可以互相调用,但不能形成闭环

  4. 如果类中没有显示的定义构造方法,系统提供一个默认的空参构造(形参列表和方法体都是空的!)

  5. 一旦手动提供了构造方法,系统都不会提供任何构造方法。

   总结:在java中,所有的类都至少有一个构造方法。

六、static关键字

  1.可以用来修饰成员(成员变量或成员方法),被static修饰的成员,不再属于实例对象,而属于类本身。不会出现在实例对象所在的堆空间,而是类所在的方法区。

  2.可以实现在同类,不同实例对象之间的数据共享。

  总结:静态的只能访问静态的,非静态的可以访问静态的和非静态的。

七、main方法的参数和使用

  String[ ] args,args就是一个数组名

  ·在启动虚拟机时,类名后的若干个空格分隔的字符串,就是给args传参。

  如:java Demo hello world nihao nice to meet you       其中,java启动,Demo类名,后面就是各个元素,都被放到args里面

八、工具类

  概念:某个类中的绝大多数方法都是静态方法,基本没有成员变量,方法中使用的数据都是来源于形参,就可以称之为工具类。

  特点:①一般不需要外界随便创造对象;

     ②只让外界通过类名使用类中的方法,要把所有构造方法私有化;

 ==================================================================

 

/*  
    思考题:
    如何设计一个类:
    让外界不能通过其构造方法去创建对象;
    但是却能通过其他方法获取这个类的一个对象的引用。
*/
class Dog{
    private Dog(){}
    //公共获取本类对象的方法
    public Dog getinstance(){
        return new Dog();
    }
}

public class Demo{
    public static void main(String[] args){
        //Dog d = new Dog().getInstance();这种构造方法不能用
        Dog d = Dog.getInstance();//这种方法是可以用的
        System.out.println(d);//打印的结果为:DOG@15db9742
    }
}

 

=======================================================================

  new      工具类的制作 & java 文档注释

 

/*
    工具类:
        一个类中,如果所有的方法都是static修饰的,那么它就是一个工具类:
      工具类中方法中使用的数据,通常都是来自于形参!!!
        
    一般工具类不提供可用的构造方法!!!
        即:在类外不让随便创建工具类的实例对象!!
        如何实现?让工具类的构造方法私有化即可!!
  数组操作的工具类:
    构造私有
    方法都是静态的
*/

 

一、类的说明文档的制作——依赖于源文件中的文档注释

 

    工具类的说明书:说明文档(API文档)
        对类的说明,方法的签名(访问修饰符,返回值类型,方法名,形参列表...)
    一般非开源的工具类,没有源码,必须得到工具类的说明书.
    
    说明书的制作:
        文档注释:
        /**  开头 */结束的多行文字都是文档注释
        其中可以使用一些比较特殊的标签:
        在类前加的标签
            @author 作者
            @version 1.0
        在方法上可以加的标签:
            @param 对参数的说明
            @return 对返回值的说明

 

/**
    这是数组操作的工具类:
    
    @author 弘扬
    @version 1.0
    
*/
public class MyArrayTools{
    //构造私有化
    private MyArrayTools(){}
    
    /**
        获取一个数组的最大值!
        @param arr 想获取最大值的数组
        @return 这个数组中的最大元素值!
    
    */
    public static int getMax(int[] arr){
        int max = arr[0];
        for(int i = 1;i<arr.length;i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        return max;
        
    }
    
    /**
        获取一个数组的最小值!
        @param arr 想获取最小值的数组
        @return 这个数组中的最小元素值!
    
    */
    public static int getMin(int[] arr){
        int min = arr[0];
        for(int i = 1;i<arr.length;i++){
            if(arr[i] < min){
                min = arr[i];
            }
        }
        return min;
        
    }
    
    /**
        显示一个数组的所有元素!!
        @param arr 想要显示的数组
    */
    public static void printArray(int[] arr){
        for(int i = 0;i<arr.length;i++){
            System.out.print(arr[i]);
            if(i != arr.length - 1){
                System.out.print(",");
            }
        }
        System.out.println();
    }
    
}

 

/*
    测试工具类
    
*/
public class ArrayToolsDemo{
    public static void main(String[] args){
        int[] arr = {1,2,3,4,5,6,7,8,9};
        
        //使用工具类获取最大值
        int max = ArrayTools.getMax(arr);
        int min = ArrayTools.getMin(arr);
        System.out.println(max+","+min);
        
        //使用工具类显示数组元素
        ArrayTools.printArray(arr);       
    }
}

 二、类的说明文档的制作依赖于源文件中的文档注释:

1.格式:

  /**    ->开始

  */     ->结束

 

2.类体前的文档注释:

  文字和标签:

  @author 作者信息

  @version 1.0

3.方法前的文档注释:

  文字和标签:

  @param 参数名 参数的说明

  @return 返回值信息说明

4.提取一个文件中的文档注释:

  不是编译过程,并且不会提取单行注释和多行注释,只提取文档注释!!!

  javadoc -d mydoc -author -version MyArrayTools.java

API文档的使用:

1.在线版

2.离线版chm格式

3.关注事项:

  所在包:java.util一类就需要导包,import java.util.Scanner,但如果是java.lang包下,直接可以用,不用导包。

  构造方法,如果是灰色的就是不让用,可用的话就就创建对象

  形参,返回值类型

  是否是static的

  从哪个版本开始

   

练习:查看API文档,使用Random类的方法 获取一个随机的 1-100之间的整型值!

/*

    API文档的使用:
        Math类
    查找API文档,Random类,使用它的某个方法,获取一个1-100之间的随机int数,改写以下程序!!    
*/
import java.util.Scanner;
import java.util.Random;

public class GuessNum{
    public static void main(String[] args){
        Scanner s = new Scanner(System.in);
        
        //
        // int r = (int)(Math.random() * 100 + 1);
        
        //改造,使用Random类的方法获取一个int随机数
        Random random = new Random();
        int r = random.nextInt(100) + 1;
        
        while(true){
            System.out.print("输入一个数:");
            int x = s.nextInt();
            if(x > r){
                System.out.println("大了");
            }else if(x < r){
                System.out.println("小了");
            }else{
                System.out.println("猜对了");
                break;
            }
        }
        
    }
}

代码块:block

三种:

  1.局部代码块:

      在方法体中出现的{}

      作用:及时释放局部变量占用的栈空间

      特点:局部代码块中的变量只在{}中有效

  2.构造代码块:

      在成员位置出现的{}

      作用:抽取出多个构造方法中共同的代码.

      特点:"一次"构造方法的调用,就执行一次,并不是一个构造方法调用,都执行一次!

  3.静态代码块:

      用static修饰的构造代码块就是静态代码块

      作用:对静态成员变量进行初始化的

      特点:随着类的加载而执行,多次创建对象,不会多次执行.

 

代码块的细节:

  每一次构造方法的调用,都会先执行构造代码块中的内容,然后才是构造方法中的内容

       并不是"每个"构造方法被调用,都会执行构造代码块中的内容!!!

静态代码块:

      伴随着类的加载而执行的,多次创建对象并不会导致静态代码块的多次执行!只是在第一次加载类的时候执行一次!!!

   就是静态代码块就执行一次,构造代码块有几个new a()就执行几个,,

多个构造代码块按出现的顺序执行!

多个静态代码块按出现的顺序执行!

 

 

*/
class A{
    
    static{
        System.out.println("静态代码块2");
    }
    
    
    {
        System.out.println("haha2");
    }
    
    
    public A(){
        this(10);
        System.out.println("空参的构造方法");
    }
    
    public A(int a){
        System.out.println("带参的构造方法");
    }
    
    {
        System.out.println("haha1");
    }
    
    static{
        System.out.println("静态代码块1");
    }
}
public class BlockDemo2{
    public static void main(String[] args){
        new A();//类的加载导致静态代码块的执行,创建对象导致构造代码块的执行!!
        new A();//创建对象导致构造代码块的执行!!
        
    }
}

   

面向对象编程三大特点之二:继承extends

继承的由来:

多个类中出现重复的成员定义,那么就可以将共同的部分抽取到一个单独的类中,让多个类和这个单独的类产生一个继承关系(使用extends关键字).

那么在多个类中就无须定义重复的部分了.

 

抽取出来的单独的类称为父类,超类,基类.

从这个父类继承的多个类则称为子类.

/*
    继承/扩展:extends
    多个类中出现了重复的成员定义:就可以把重复的内容抽取到一个单独的类中.
    让多个类和单独的类产生一个关系.在多个类中,就无需再定义重复的内容.
    被抽取出来的类称为父类,超类,基类.
    多个类称为子类.
  
*/
/*
class Student{
    public String name;
    public int age;
    
    public void eat(){
        System.out.println("eat()...");
    }
}

class Teacher{
    public String name;
    public int age;
    
    public void eat(){
        System.out.println("eat()...");
    }
}

*/

class Person{
    public String name;
    public int age;
    
    public void eat(){
        System.out.println("eat()...");
    }
}

//extends关键字后是父类,前是子类,子类中无须再定义父类中出现的代码
class Student extends Person{
    
}

//extends关键字后是父类,前是子类,子类中无须再定义父类中出现的代码
class Teacher extends Person{
    
}

public class ExtendsDemo{
    public static void main(String[] args){
        
        Student s = new Student();
        s.name = "zhangsan";
        s.age = 10;
        System.out.println(s.name +","+ s.age);
        s.eat();
        
        Teacher t = new Teacher();
        t.name = "lisi";
        t.age = 20;
        System.out.println(t.name +","+ t.age);
        t.eat();
    }
}

 

继承的优点:

1.实现了代码的复用,简化代码书写.

2.是多态的前提!

 

语法:

修饰符 class 子类名 extends 父类名{...}

 

继承的特点:

1.Java不支持多继承,支持多层继承!!!

一个类只能有一个直接父类,父类还可以再有父类...,也就是继承体系.

2.父类私有成员不能被继承,公有的方法能被继承,可以通过公有的方法,间接的访问父类的私有成员!!!

 class A{ }

class B extends A{ }

class C extends B{ }

 

/*
    Java中继承只支持单继承,不支持多继承
    一个子类只能有一个直接父类.不能有多个父类.
    
    java中不支持多继承,支持多层次继承!!!
    
    父类中私有的成员不能被继承!!
    
    
    
*/

class GrandFather{
    
}
class Father extends GrandFather{
    private int age = 10;
    
    public int getAge(){
        return age;
    }
    
    
    private void test(){
        System.out.println("Father.test()");
    }
    
}
class Mother{
    
}

class Son extends Father{
    //getAge();
}


/*
class Son extends Father,Mother{
    
}
*/

public class ExtendsDemo2{
    public static void main(String[] args){
        // Father f = new Father();
        // System.out.println(f.age);
        
        
        Son s = new Son();
        // System.out.println(s.age);//父类私有成员不能被继承!!!
        System.out.println(s.getAge());
        
        
        
    }
}
/*
    继承关系中,子父类中的成员变量的关系:
    1.子类中没有任何和父类同名的成员变量
    2.子类中出现了和父类同名的成员变量,使用子类的
    
    子类的方法中,使用到的变量,有三种情况:
    1.先在方法体内找
    2.在子类的成员位置找
    3.在父类的成员位置找
    
*/

class Father{
    int a = 10;

}
class Son extends Father{

    // int a = 30;
    //子类特有的变量
    int b = 20;
    
    public void test(){
        // int a = 40;
        System.out.println(a);//
        System.out.println(b);
    }
}

public class ExtendsDemo3{
    public static void main(String[] args){
        new Son().test();
    }
}

   

super关键字

super关键字和this关键字的作用类似.

  this表示的是当前正在调用当前这段代码的对象的引用.

  super表示一个对象的直接父类对象的引用!

/*
    super关键字:
        子类对象所在的堆空间中包含的一个父类对象的引用!
        子类对象创建前,父类对象必须先创建出来!!!这个过程是系统自动完成的.
        
    super关键字的使用场景:
    1.子类出现和父类同名的成员,父类的成员会被隐藏.使用super可以访问到父类被隐藏的成员super.变量名
    2.在子类方法中显式调用父类的某些方法.super.方法名()
    3.在子类的构造方法中,显式调用父类的构造方法!!!
        子类的构造方法默认有一条语句:super(); 这句就是在调用父类的空参构造方法.把父类对象创建出来
        如果父类没有空参构造方法,那就会报错.
        此时,一般会调用父类其它的构造方法,super(xxx)
        
    java 中每个类的构造方法的第一条语句,默认都是super();
        
*/
class Father{
    int age = 30;
    
    //父类空参构造
    public Father(int a){
        System.out.println("父类空参构造");
    }
    
    
    public void method(){
        System.out.println("father.method");
    }
}

class Son extends Father{
    int age = 10;
    
    //子类的所有构造方法中,默认第一条都是super();
    //除非子类的构造方法中使用this调用本类的其它构造方法,或者super(xxx);
    public Son(){
        //super();
        //调用父类带参的构造方法
        super(0);
        System.out.println("子类的空参构造");
    }
    
    
    public Son(int x){
        this();//此时就没有super();了
    }
    
    public Son(int x,int y){
        super();
    }
    
    
    public void test(){
        //引用父类中被隐藏的成员变量
        System.out.println(age + "," + super.age);
    }
    
    //子类中出现了和父类同样的方法,称之为重写!
    public void method(){
        //调用父类被隐藏的方法
        super.method();
        System.out.println("son.method");
    }
    
}
public class SuperDemo{
    public static void main(String[] args){
        Son s = new Son();//
        // s.test();
        // s.method();
    }
}

    

 

:可以理解为:一个实例对象的内部都包含一个其直接父类的对象!

  这样做的目的是为了保证能正确的从父类中继承成员!!!

例如父类中的实例变量,是属于父类实例对象的,存在于父类对象所在的堆空间中.

  如果父类对象不存在的话,那么子类对象就不能继承这个成员了!  

从图中也可以看出:

  1.其实父类对象中的所有成员(包括私有的),都是存在的,只不过不能直接访问而已!

  2.父类被覆盖的成员,可以通过super关键字访问

 

方法的重写:override/overwrite

子类中出现和父类方法签名一致的方法,此时父类的方法被隐藏了.即:子类重写了父类的方法.

 

子类重写父类的方法:

  1.只能在访问权限上放大.其余的都保持一致!!!

  2.静态的方法只能使用静态方法重写.

  3.子类重写方法中想调用父类被隐藏的方法,可以使用super.方法名(xxx)的方式!!!

但是,static方法中不能使用super关键字!此时只能用类名调用.

   A.全否定  B.部分保留

/*
    方法的重写:overwrite override
        子类中出现了父类一样的成员方法.父类中的方法就被"覆盖"了.称为子类重写了父类的方法.
        
    1.子类重写父类的方法,权限修饰符可以扩大范围:或者保持一致!!!
    2.除了访问权限外,其余都和父类方法保持一致!!!
    3.子类重写的方法中,可以通过super.方法名(xxx)的方法,去调用父类被覆盖的方法.    
    
    static静态方法中,不能出现this,super关键字
        不论this,super它们都是实例对象的引用!!
        static出现时,还没有实例对象.
        
*/
class Father{
    //什么都不写,就是默认的访问权限修饰符,
    void test(){
        System.out.println("father.test()");
    }
    
    public static void method(){
        System.out.println("father static method");
    }
}

class Son extends Father{
    //重写父类方法
    public void test(){
        //访问被重写的父类方法
        super.test();
        System.out.println("son.test()...");
    }
    
    /*
    public static void method(){
        // super.method();
        Father.method();
        System.out.println("son static method");
    }
    */
    
    //子类特有的方法
    public void test2(){
        
    }
    public void test3(){
        
    }
}

public class OverwriteDemo{
    public static void main(String[] args){
        Son s = new Son();
        // s.test();
        s.method();
        s.test2();
        
    }
}

    

面试题:

说说override,overwrite,overload三者的区别.

 

 

静态方法中不能出现this或者super关键字

因为:不论this或者super都是堆空间中对象的引用.

但是static方法是随着类的加载而存在的,此时还没有存在实例对象.

 

final关键字:

  1. final + 类名:此类不能有子类
  2. final + 方法名:此方法不能被子类重写
  3. final + 变量名:只能被赋值一次!也就是final常量!

 

Java中的常量有两种:

1.字面量常量

2.final常量

它们的特点是值是不可变的!

 

静态的final变量:

    1.定义的时候就赋值

    2.定义时不赋值,在静态代码块中赋值

 

非静态的final变量:

    1.定义的时候就赋值

    2.定义时不赋值,在构造代码块中赋值

    3.定义时不赋值,构造代码块中不赋值,在构造方法中赋值

    总结:非静态的final变量,只需要在构造方法调用完成之前赋值就可以了!!

 

最常用的场景就是在定义的时候就赋值!!! 

 

/*
    final关键字:
        final + 类名:不能有子类
        final + 方法名:方法不能被子类重写
        final + 变量名:只能被赋值一次!
        
    静态的final变量:
        1.定义的时候就赋值
        2.定义时不赋值,在静态代码块中赋值
        
    非静态的final变量:
        1.定义的时候就赋值
        2.定义时不赋值,在构造代码块中赋值
        3.定义时不赋值,构造代码块中不赋值,在构造方法中赋值
        总结:非静态的final变量,只需要在构造方法调用完成之前赋值就可以了!!
        
    最常用的场景就是在定义的时候就赋值!!!    
*/
/*
final class A{
    
}

class B extends A{
    
}
*/

class A{
    public final void test(){
        System.out.println("final test()");
    }
}

class B extends A{
    static final int b = 10;
    static{
        b = 10;
    }
    
    final int a;
    
    {
        a = 30;
    }
    
    public B(){
        // a = 20;
    }
    
    /*
    //final方法不能被重写
    public void test(){
        System.out.println("B  final test()");
    }
    */
}

public class FinalDemo{
    public static void main(String[] args){
        System.out.println(new B().b);
    }
}

   

抽象类:abstract关键字

抽象方法:是没有方法体的方法,就是抽象方法.

抽象类:包含抽象方法的类,就是抽象类.

 

抽象方法和抽象类,都必须使用abstract关键字修饰.

 

抽象类的特点:抽象类不能手动的去用new对象!

抽象类是依赖其实现子类去实例化对象的.

:抽象类中定义的抽象方法,只有在子类对象中才能使用!!!

 

抽象类的继承:

抽象类的子类如果把抽象父类中的所有抽象方法都实现了,那么此子类就是一个实现子类,这个子类就可以创建对象.

否则,只要没有完全把所有的抽象方法都实现,此子类就依然是一个抽象子类.依然不能实例化对象.

/*
    抽象方法:没有方法体的方法(就是没有{}的方法),就是抽象方法.必须被abstract关键字修饰.
    一旦一个类中包含了抽象方法,那么本类也是一个抽象类,也必须用abstract关键字修饰.
    
    
    抽象类不能直接实例化对象.
    抽象类是通过子类实例化对象的.
    
    子类必须实现抽象父类中的所有抽象方法.否则子类也是一个抽象类.
    
    
*/
abstract class Animal{
    //没有方法体的方法,就是抽象方法,必须用abstract修饰!!!
    public abstract void eat();
}

//实现子类:不包含任何抽象方法的类
class Dog extends Animal{
    //实现抽象方法
    public void eat(){
        System.out.println("dog eat");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("cat eat");
    }
}


public class AbstractDemo{
    public static void main(String[] args){
        //抽象类是否能实例化对象?
        // Animal a = new Animal();// Animal是抽象的; 无法实例化
        
        Dog d = new Dog();
        d.eat();
        
        Cat c = new Cat();
        c.eat();
    }
}

 

  回顾

一、文档注释

1.文档注释→说明书的制作

  格式:/**         */

 1>直接出现的文字,特殊的标签;

 2>类上:

  @author

  @return

 3>方法上:

  @param 参数名

  @return

   4> 使用特殊的工具提取文档注释,提取一个源文件中的文档注释成html页面。

  语法:javac -d c:/mydocs -author -version Demo.java

    其中javadoc命令只是提取文档注释,并不会编译源文件!

二、API文档的使用

1一般情况下,知道类名,去搜索相关的说明

  1>包名,是否是java.lang包下,是,则程序直接使用,否则需要导包

  2>构造方法是否可用,可以,则一般情况下会创建对象,在使用他的方法。

   如果不能用构造方法:

      此类是工具类;

      此类提供了静态放发,用于获取本类的一个实例对象;

      此类是一个抽象类,只能是通过实现子类实例化!

  3>方法的修饰符:

    static

    返回值类型

    方法参数列表,返回值信息

    方法异常信息

2.代码块的执行顺序

  静态→构造代码块→构造方法

 

三、面向对象的特点之二:继承

  1.概念:继承是java中实现代码复用的方式!

  2.子类中出现和父类同名的成员(成员变量和成员方法)

    父类中的成员都是被隐藏起来了,并没有消失!

    super关键字可以把父类隐藏的成员暴露出来!!

  3.子类方法中使用变量的查找顺序:

    1.>先在局部位置(直接在方法体中定义的变量,方法的形参上)找

    2.>在子类的成员位置找

    3>在父类的成员位置找

四、方法的重写

  子类中出现了和父类方法签名一致的方法,就是方法的重写!!

  方法重写的特点:

    子类方法可以把访问权限放大,其余的都和父类方法保持一致!

    静态方法只能用静态重写!!(静态方法实际上是没有重写的概念的!!)

五、super关键字

  1.子类方法中使用被隐藏的父类变量:super.变量名

  2.子类方法中使用被重写的父类方法:super.方法名(xxxx)

  3.子类构造方法中使用super(xxx),调用父类的构造方法

  4.子类所有构造方法默认第一句都是 super()

    除非子类构造第一句使用的是,this(),super(xxxx)

  5.子类实例化对象时具体步骤:

    1>执行子类的类加载过程(伴随着子类静态代码块的执行,直接父类也会执行加载)

    2>成员变量的初始化(系统默认初始化,显示初始化)

    3>构造方法初始化(构造代码块,构造方法)

    4>把实列对象的地址返回

    在子类成员变量初始化,构造代码块,构造方法中,如果出现了其它的类的实例化过程,那么这个被引用的类的初始化过程也会被执行(1-4步)

Dog{
    static{}

    {}
    int age = 10;
    public Dog(){...}
}

Person{
    String name = null;
    Dog d = null;

    {
        
    }
    public Person(){...}
}

 

六、final关键字

  1. final + 类名:此类不能有子类(不能被继承)
  2. final + 方法名:此方法不能被子类重写
  3. final + 变量名:只能被赋值一次!也就是final常量!

 

ExtendsDemo.java 子类实例化的具体过程

七、抽象类:

  1>抽象类:使用abstract修饰的类就是抽象类,包含抽象的方法的类就是方法类!

  2>抽象方法:没有方法体的方法就是抽象方法!

 

  抽取父类时,子类的方法签名相同,但是具体实现不同,父类中只能抽取方法签名

  这个没有方法体的方法就是抽象方法!!

  

  题目:抽象类如何使用? 

  • 抽象类的特点:抽象类不能手动的去用new对象!
  • 抽象类是依赖其实现子类去实例化对象的.
  • :抽象类中定义的抽象方法,只有在子类对象中才能使用!!!

 

 ==============

作业:

1.Java中实现继承使用的关键字是?

2.Java中是否有多继承?是否有多层继承?

3.父类中私有的成员是否能被子类继承?是否能被使用?

4.一旦子类中出现了和父类一样的成员定义的话,父类中的同样的成员如何被使用?

5.父类构造方法能被子类继承么?

6.说说override,overwrite,overload三者的区别.

7.为什么子类的构造方法默认第一句都是super();?

(子类实例化之前父类的实例化对象必须先存在?)

子类需要从父类中继承一些成员,而父类构造方法的主要目的就是对成员进行初始化的.

子类实例化对象前,父类的构造方法必须被调用!!!

 

8.子类重写父类方法的时候,能改变的部分是?不能变的部分是?

只有访问权限可以放大,或者相同.其余都不能变!

 

9.什么是抽象方法?什么是抽象类?抽象类如何实例化?

没有方法体的方法就是抽象方法.

使用abstract修饰的类就是抽象类,其中不一定包含抽象方法.

抽象类不能直接实例化,通过实现子类间接实例化!!

 

 

编码:

1.设计一个Phone类,拥有基本的属性和一个基本的打电话的功能.

设计一个NewPhone类,从Phone类继承基本的属性和功能,并重写打电话功能.在基本的打电话功能基础上,增加显示通话时间的功能.

分别对两个类的对象做测试.

 

2.设计一个抽象类,包含一个抽象方法,让不同的子类有不同的实现.并做测试!

 

3.思考题

 

编程实现如下场景:

动物园饲养员负责饲养动物,他有一个饲养的方法,只要是动物他都可以进行饲养.

动物有两种:Dog,Cat,它们都有一个show方法.用于显示各自饿了的信息,每种动物实现的细节可能不同.

饲养员在饲养动物时,先让动物show方法调用一下,然后再喂食.

 

使用继承和抽象类的知识对以上场景进行模拟实现.

提示:饲养员的饲养方法的参数是什么类型?是具体的Dog,还是Cat?还是一个其他的类型?

 =====================

 

   

 

posted @ 2018-10-30 21:51  杜菲  阅读(256)  评论(0编辑  收藏  举报