继承extends、super、this、方法重写overiding、final、代码块_DAY08

1:Math类的随机数(掌握)

      类名调用静态方法。

      包:java.lang

      类:Math

      方法:public static double random():

           Java.lang包下的类是不用导包就可以直接使用的。

    产生1-100之间的随机数:

          int number = (int)(Math.random()*100)+1;

2:如何使用API。(掌握)

      A:找到文档,打开文档。

      B:点击左上角的显示变成隐藏,然后点击索引

      C:你应该知道你要找谁?Math

        所以,你就在那个输入框里面输入Math,然后回车,再回车。

      D:看这个类的结构

               java.lang

               类 Math

               java.util

               类 Scanner

          如果是java.lang包下的类,是可以直接使用的。(Math),否则,就需要导包才能使用。(Scanner)

     E:看看对这个类的说明。

     F:看构造方法

          名称:字段 --  成员变量   -- 属性。

         a:有构造方法,那么,就通过构造方法创建对象使用。

         b:没有构造方法,那么,这个类的成员一般都是静态。

             通过类名调用。

     G:按照正常的操作使用方法。

           左边:

                 是否静态:如果静态修饰,那么可以通过类名调用。否则,就必须创建对象调用。

                 是否有明确返回值:如果是void类型,就直接调用即可。否则,就可以输出或者赋值。

           右边:

                 看方法名:不要写错了。

                 看参数:看参数类型及个数。

3:继承(掌握)extends

      (1)把多个类中的相同的属性和行为进行抽取,封装到一个类中,然后再建立新类的时候,不需要从头做起,继承刚才定义的那个类即可。

      (2)好处:

           A:提高代码的复用性。

           B:让类与类之间产生了一个关系,是多态的前提。

      (3)什么时候使用继承?

           A:如果类之间存在着:is a 的关系,就可以考虑使用继承。

           B:不要为了继承部分功能,而去使用继承。详细见例子:

       /*

    继承一定要符合is a 的关系。

*/

class Demo5

{

    public static void main(String[] args)

    {

       System.out.println("Hello World!");

    }

}

class Animal

{

    String name = "巴马";

    int age = 80;

 

    public void eat(){

       System.out.println("吃");

    }

 

    public void sleep(){

       System.out.println("睡");

    }

 

    private void method(){}

}

 

class Cat extends Animal {

   

    public void climb(){

       System.out.println("爬树");

    }

 

    public void catchM(){

       System.out.println("抓耗子");

    }

 

    public void eatM(){

       System.out.println("生吃耗子");

    }

}

 

class Person extends Cat{}  //不要为了人有“爬树”和“抓耗子”的工能,而去继承Cat类,语法上没有错误,但是在逻辑上有问题。因为Cat类还有“生吃耗子”工能,而人没有。

 
View Code

          (4)继承的特点:

           A:Java只支持单继承,不支持多继承。

                   为什么?如果支持多继承,就会有调用不明确的问题。

           B:Java支持多层(重)继承。

       例子:

   /*

    继承的特点:

       支持单继承,不支持多继承。

       支持多层继承。

       Object是多有类的直接或间接父类。

*/

class Demo4

{

    public static void main(String[] args)

    {

       Person p = new Person();

       System.out.println(p.name);

       System.out.println(p.age);

 

       p.eat();

       p.sleep();

    }

}

 

class Animal

{

    String name = "巴马";

    int age = 80;

 

    public void eat(){

       System.out.println("吃");

    }

 

    public void sleep(){

       System.out.println("睡");

    }

 

    private void method(){}

}

 

class Pig extends Animal{}

 

//class Person extends Monkey,Animal{}    //一个类不能多继承

 

class Monkey extends Animal{}

class Person extends Monkey{}            //支持多层继承
View Code

      (5)super和this的区别?

           A:super是一个关键字,代表父类的存储空间标识。(可以理解为父亲对象的引用,单实际不是父亲对象的引用)

           B:它和this的用法相似

                 a:成员变量

                      this.变量  --  本类的

                      super.变量 --  父类的

                 b:构造方法

                      this(...)  --  本类的

                      super(...) --  父类的

                 c:成员方法

                      this.方法名() --  本类的

                      super.方法名() --  父类的

                         例子:

/*

    super:代表父类的内存空间

    使用方式:

       1、super区分父类成员变量与子类成员变量

       2、super放在构造方法中第一行,用来调用父类的构造方法

*/

class Demo6

{

    public static void main(String[] args)

    {

       //Person p = new Person();

       //p.showMe();

 

       Person p2 = new Person("巴豆",3);

       p2.showMe();

    }

}

 

class Animal

{

    String name = "巴马";

    int age = 80;

   

    //定义空参构造

    /*

    public Animal(){

       System.out.println("我是父类的空参构造方法");

    }

    */

    //定义两个参数构造

    public Animal(String name,int age) {

       System.out.println("我是父类的有参构造方法");

       this.name = name;

       this.age = age;

    }

 

    public void eat(){

       System.out.println("吃");

    }

 

    public void sleep(){

       System.out.println("睡");

    }

 

    private void method(){}

}

 

class Person extends Animal 

{

    String name = "巴驴";

    int age = 60;

   

    public Person(){

       //super();      //默认都有super()构造方法

       super("aaa",100);

       System.out.println("我是子类的空参构造方法");

    }

   

    public Person(String name,int age) {

       //this();       //this不可以与super同时调用构造方法

       super(name,age);

      

       System.out.println("我是子类的有参构造方法");

       this.name = name;

       this.age = age;

    }

 

    public void showMe(){

       String name = "巴骡";

       int age = 70;

       //局部变量直接写变量名即可

       System.out.println("姓名:"+name+" 年龄:"+age);

       //本类的成员变量加this区分

       System.out.println("姓名:"+this.name+" 年龄:"+this.age);

       //父类的成员变量加super区分

       System.out.println("姓名:"+super.name+" 年龄:"+super.age);

       //如果同时存在,则就近原则

    }

}
View Code

           (6)继承关系内存图:

     (7)子父类实例化过程

             子类中所有的构造函数默认都会访问父类中空参数的构造函数,原因是构造方法中第一行默认的super(),子类具备父类中的数据,所以需要先明确父类是如何初始化的,即调用父类的构造方法。父类存储空间优于子类对象。

大致顺序:

     (8)标准的继承关系代码

  /*

    标准的继承关系代码

*/

class Demo9

{

    public static void main(String[] args)

    {

       Cat cat = new Cat("Tom",5,"黄黑条");

       cat.method();

       cat.method2();

       cat.setName("kitty");

       cat.setColor("pink");

 

       cat.showMe();

    }

}

 

class Animal

{

    private String name;

    private int age;

 

    public Animal() {}

 

    public Animal(String name,int age) {

       this.name = name;

       this.age = age;

    }

 

    public void method(){

       System.out.println("我是父类的第一个方法");

    }

 

    public void method2(){

       System.out.println("我是父类的第二个方法");

    }

 

    //-----------------------------------------------------------------

 

    public void setName(String name) {

       this.name = name;

    }

    public String getName() {

       return name;

    }

 

    public void setAge(int age) {

       this.age = age;

    }

 

    public int getAge() {

       return age;

    }

}

 

 

class Cat extends Animal

{

    private String color;

 

    public Cat() {}

 

    public Cat(String name,int age,String color) {

       super(name,age);

       this.color = color;

    }

 

    public void method(){

       System.out.println("我是子类的重写的第一个方法");

    }

 

    public void showMe(){

       System.out.println("name:"+super.getName()+" age:"+getAge()+" color:"+color);

    }

   

    public void setColor(String color) {

       this.color = color;

    }

    public String getColor() {

       return color;

    }

}

 
View Code

      (9)子父类中成员变量的用法:

           A:名称不同,这个太简单了。

           B:名称相同,子类对象的在使用的时候:

                 先找子类局部范围

                 再找子类成员范围

                 最后找父类成员范围

                 父类的父类成员范围

      (10)子父类中成员方法的用法:

             A:名称不同,这个太简单了。

             B:名称相同,子类对象的在使用的时候:

                   先找子类的

                   再找父类的

             C:方法重写(overiding)

                 要求:

                         a.子类方法访问权限需要大于等于父类方法访问权限

                        b.返回值类型:

                             基本类型/void:必须相同

                             引用类型:子类返回值类型必须为父类返回值类型的子类

                        c.函数名相同

                        d.参数列表:相同为重写,不同时为重载

               应用:子类需要父类功能,但又在功能上又有多增加时,可以复写父类方法。子类比父类更强大。

               注意事项:

                        a.父类中私有方法不可以被覆盖。

                        b.在子类中想调用父类自己的方法可以使用super关键字

                        c.静态只能覆盖静态。(这个不能算,因为静态跟类相关)

例子:

class OveridingMethod {

    public static void main(String[] args) {

        Zi2 zi2 = new Zi2();

        zi2.method2();

    }

}

 

class Fu {

    public void method() {

    }

}

 

class Zi extends Fu {

    public void method() {

    }

}

 

class Fu2 {

 

    Fu fu = new Fu();

 

 

    public Zi method2() {    ////报错,子类返回值类型必须为父类返回值类型的子类,此处不是。

        System.out.println("我是子类2的方法");

        return zi;

    }

}

 

class Zi2 extends Fu2 {

    Zi zi = new Zi();

 

    public Fu method2() { //报错,子类返回值类型必须为父类返回值类型的子类,此处不是。

        System.out.println("我是子类2的方法");

        return fu;

    }


}
View Code

    (11)子父类中构造方法的用法:

           A:子类的初始化过程中,首先回去执行父类的初始化动作。

                因为子类的构造方法中默认有一个super()。

                为什么?子类要使用父类的成员变量,这个初始化,必须在子类初始化之前完成。

                所以,子类的初始化过程中,会先执行父类的初始化。

          B:如果父类没有无参构造方法

               A:使用super调用父类的带参构造。推荐方式。

               B:使用this调用本身的其他构造。

4:代码块(面试题)

          (1)代码块:写代码的区域,使用{}作为范围限定

            局部代码块:

                 位置:方法内

                 作用:控制变量作用域

           构造代码块:

                 位置:成员位置,类中,方法外

                 作用:将构造器中相同代码抽取,在构造器前执行

          静态构造代码块:

                 位置:成员位置,类中,方法外

                 作用:只在第一次创建对象时初始化一次

/*
    代码块:写代码的区域,使用{}作为范围限定

    局部代码块:
        位置:方法内
        作用:控制变量作用域
    构造代码块:
        位置:成员位置,类中,方法外
        作用:将构造器中相同代码抽取,在构造器前执行
    静态构造代码块:
        位置:成员位置,类中,方法外
        作用:只在第一次创建对象时初始化一次

    默认初始化>显示初始化>构造代码块>构造方法
*/
class Demo2 
{
    public static void main(String[] args) 
    {
        int i = 10;
        {
            int i2 = 20;
        }
        System.out.println(i);
        //System.out.println(i2);  超出作用域

        Person p = new Person();
        Person p2 = new Person("巴马",80);
        p2.showMe();

    }
}

class Person
{
    //定义Person类的属性
    private String name =  "巴骡";
    private int age = 60;
    
    //定义一个构造代码块
    {
        System.out.println("我是一个构造代码块");
        name = "巴驴";
        age = 70;
        System.out.println("我是要初始化的步骤1");
        System.out.println("我是要初始化的步骤2");
        System.out.println("我是要初始化的步骤3");
        System.out.println("我是要初始化的步骤4");
    }

    static{
        System.out.println("我是一个静态构造代码块");
    }

    //定义Person类的构造方法
    public Person(){
        System.out.println("我是空参构造方法");
    }
    public Person(String name,int age){
        System.out.println("我是有参构造方法");
        //this.name = name;
        //this.age = age;
    }

    public void showMe(){
        System.out.println("name:"+name+" age:"+age);
    }
    
    //定义Person类的普通方法
    public void eat(){
        System.out.println("吃了");
    }

    public void sleep(){
        System.out.println("睡了");
    }
    //定义Person类的getters和setters
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge(){
        return age;
    }
}    
View Code

      (2)执行顺序:

           静态代码块 --> 构造代码块 --> 构造方法

           默认初始化>显式初始化>构造代码块初始化>构造方法初始化

      (3)注意事项:

           静态代码块只执行一次

 5:final(掌握)(简单总结为:修饰的东西不能变!)

      (1)是一个关键字,可以用于修饰类,成员变量,成员方法。

      (2)特点:

           它修饰的类不能被继承。

           它修饰的成员方法是不能被子类重写的。

           它修饰的成员变量是一个常量。常量必须有值,且常量的值只能赋值一次。如果是成员变量,只需要在对象创建之前赋值即可。

           引用类型常量可以更改其堆内存对象中的值。

例:

     a.final修饰的类不能被继承。

class Demo10 {

    public static void main(String[] args) {

 

    }

}

 

final class Fu{   // 修饰类,类不可以被继承。

}

 

class Zi extends Fu{

}
View Code

   b.它修饰的成员方法是不能被子类重写的.

 class Demo10 {

    public static void main(String[] args) {

 

    }

}

 

class Fu{

    final public void showMe(){} //修饰方法,方法不可以被重写。

}

 

class Zi extends Fu{

    public void showMe(){}

}

 
View Code

   c.常量必须有值

 class Demo10 {

    public static void main(String[] args) {

       final int a;

        System.out.println(a);  //常量必须有值。此处会报错

 

    }

}
View Code

   d.常量的值只能赋值一次

 class Demo10 {

    public static void main(String[] args) {

       final int a=10;

        a=20;  //常量的值只能赋值一次,此处报错

        System.out.println(a);

    }

}
View Code

     e.如果是成员变量,只需要在对象创建之前赋值即可

class Demo10 {

    public static void main(String[] args) {

        Fu fu = new Fu("唐嫣");  //创建对象时赋值

    }

}

 

class Fu {

    //成员变量

    final private String name;

    final private int age = 20; //创建成员变量时赋值

 

    //构造器

    public Fu(String name) {

        this.name = name;

    }

}
View Code

  f.引用类型常量可以更改其堆内存对象中的值,引用类型变量被final修饰,不能再指向其他对象地址

    

6:同一个文档里不能有两个以上Public修饰的类

         public class name{}

         public class age{}    //同一个文档里有两个以上Public修饰的类会报错。

        

附:

  题一:面向对象基础知识全涵盖例(标准学生类的定义及使用)

 /*

    标准学生类的定义及使用

*/

class Test

{

    public static void main(String[] args)

    {

       /*

           创建对象

           使用对象调用方法

           使用对象调用方法访问属性

       */

       Student s = new Student();

       s.setName("近平");

       s.setAge(24);

       s.address = "上海,广州也可以!";

      

       s.study("java");

       System.out.println(s.eat());

       System.out.println(s.hitBeanBean(3));

       Student.jiayou("i have a dream,a code dream and a money dream!");

      

 

       Student s2 = new Student("克强",26);

 

       s2.study("SQL");

       System.out.println(s2.eat());

       System.out.println(s2.hitBeanBean(6));

       Student.jiayou("i have a dream,a code dream and a money dream!");

 

    }

}

 

 

/*

    给类命名

    成员变量的定义

    构造方法的定义

    普通方法的定义

    getters/setters

*/

//给类命名

class Student

{

    //成员变量的定义

    private String name;

    private int age;

    public static String address = "北京,梦开始的地方!";

 

    //构造方法的定义

    public Student(){}

    //一个参数的构造也可以定义

    public Student(String name,int age) {

       this.name = name;

       this.age = age;

    }

    //普通方法的定义

    public void study(String neirong) {

       System.out.println("我学的是"+neirong);

    }

 

    public String eat(){

       return "我已经吃了!";

    }

 

    public String hitBeanBean(int cishu) {

       return "我今天打了"+cishu+"次豆豆。我很舒服。";

    }

 

    public static void jiayou(String xuanyan) {

       System.out.println(xuanyan);

    }

 

    //getters/setters

    public void setName(String name) {

       this.name = name;

    }

 

    public String getName(){

       return name;

    }

 

    public void setAge(int age) {

       this.age = age;

    }

 

    public int getAge(){

       return age;

    }

}
View Code
原文地址:https://www.cnblogs.com/hezhiyao/p/7475914.html