JAVA入门到精通-第10讲-访问修饰符-重载-覆盖

时间:2022-03-15 19:24:52
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 Test是 一个公有类,pubic static void mian是个主函数,本身是个入口而已;

  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
    JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 因为xiaoqiang的Dog是私有的;
 
   JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  引入xiaoqiang包里的所有的类;引入Cat;
 
  如果想访问其他包的私有属性,需要打开接口;提供一个成员方法 

xiaoqiang:
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
xiaoming:
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  因为小学生、中学生、大学生好多属性都是相同的;解决代码复用问题;
 子类不需要重新定义;

  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 extends继承;

JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
成员属性,成员变量可以被继承;
 printName成员函数也会被小学生、中学生、大学生继承;

JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 父类的私有属性是不能被继承的;

 通过接口解决不能多重继承的小问题;

  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 Kid 拥有了Stu和Pupil的属性和方法;
 JAVA中继承的层次没有多做限制;
 
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
 有些东西继承必须要用系统的;
   JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
 JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
为了做同一件事需要切换比较麻烦;

JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  只是访问修饰符不一样,不能构成重载;

JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
  JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
Cat想有自己的方法,不用父类的cry()方法;

JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
 这个cry()方法覆盖了父类的;构成了一个覆盖;
 

继承--为什么有?[Demo117.java]

//功能:说明继承的重要性

 

x
 
1
2
package com.abc;//包名
3
public class Demo117 {
4
    public static void main(String[] args) {
5
        Pupil p1=new Pupil();
6
        p1.printName();
7
    }
8
}
9
 
10
//将学生的共有属性提取,做一个父类
11
class Stu{
12
    //定义成员属性
13
    protected int age;
14
    public String name;
15
    public float fee;
16
    private String job;//私有将不被继承
17
   
18
    //编程中,如果你不希望子类继承某个属性或方法
19
    //则将其声明为private即可
20
    public void printName(){
21
        System.out.println("名字"+this.name);
22
    }
23
}
24
 
25
//小学生类
26
class Pupil extends Stu{
27
    //交学费
28
    public void pay(float fee){
29
        this.fee=fee;
30
    }
31
}
32
//幼儿
33
class Pre extends Pupil{
34
    //交学费
35
    public void pay(float fee){
36
        this.fee=fee*1.5f;
37
    }
38
}
39
//中学生类
40
class MiddleStu extends Stu{
41
    //交学费
42
    public void pay(float fee){
43
        this.fee=fee*0.8f;
44
    }
45
}
46
//大学生类
47
class ColStu extends Stu{
48
    //交学费
49
    public void pay(float fee){
50
        this.fee=fee*0.1f;
51
    }
52
}

继承--解决之道

继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类(比如刚才的Student),在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends语句来声明继承父类:

    语法:class 子类 extends 父类

这样,子类就会自动拥有父类定义的某些属性和方法

 

继承--深入讨论

1、父类的哪些属性(变量)、方法被子类继承了?并不是父类的所有属性、方法都可以被子类继承

       父类                         子类

    public 属性;                public 属性;

    protected 属性;     继承    protected 属性;

    private 属性;                     属性;

            属性;

    public 方法;                public 方法;

    protected 方法;             protected 方法;

    private 方法;                         方法;

            方法;      

2、结论

从图可以看出,父类的public修饰符的属性和方法;protected修饰符的属性和方法;默认修饰符属性和方法被子类继承了,父类的private修饰符的属性和方法不能被子类继承。

 

继承--注意事项

1子类最多只能继承一个父类(指直接继承)

2java所有类都是Object类的子类 (所有的子类都可以逐级继承,例:->->->)

3JDK6中有202个包3777个类、接口、异常、枚举、注释和错误

4、在做开发的时候,强烈建议大家多查jdk帮助文档

5、在使用类时,实在不知道怎么办,多使用搜索引擎

 

定义类的改进

在提出包后,我们类的定义就更加完善了:

class 类名{     class 类名{     class类名{      package包名;   

成员变量;     成员变量;     成员变量;     class 类名{ 

}               成员方法;       构造方法;       成员变量;

                }               成员方法;       构造方法;

                                }               成员方法;

                                                }  

  ↓←←←←←←←←←←←←←←←←←←←←←←←←←

package 包名;

class 类名 extends 父类{        待定

    成员变量;                 ....

    构造方法;

    成员方法;

}

 

-------------------------------------------------------------------------------

java面向对象编程(2)--方法重载(overload)

方法重载(overload)

按顺序,我们应该讲解多态,但是在讲解多态前,我们必须讲解方法重载和方法覆盖(override)

请编写一个类(Abc),编写方法可以接收两个整数,返回两个数中较大的数[Demo119.java]

x
 
1
//方法重载(overload)getMax
2
public class Demo119{
3
    public static void main(String []args){
4
        Abc2 abc1=new Abc2();
5
        System.out.println(abc1.getMax(12,14));
6
        System.out.println(abc1.getMax(24f,20f));
7
   }
8
}
9
 
10
class Abc2{
11
    //返回较大的整数
12
    public int getMax(int i,int j){
13
        if(i>j){
14
            return i;
15
       }else{
16
            return j;
17
         }
18
   }
19
    public float getMax(float a,float b){
20
        if(a>b){
21
            return a;
22
       }else{
23
            return b;
24
         }
25
    }
26
    //如果只是返回类型不一样,能否构成重载?不能够构成重载
27
/* public double getMax(float d,double c){
28
        if(c>d){
29
            return c;
30
        }else{
31
            return d;
32
         }
33
    }
34
    //如果只是控制访问修饰符不同,能否构成重载?不能够构成重载
35
    protected float getMax(float c,float d){
36
        if(c>d){
37
            return c;
38
        }else{
39
            return d;
40
         }
41
    }*/
42
}

 

方法重载(overload)概念

简单的说:方法重载就是在类的同一种功能的多种实现方式,到底采用哪种方式,取决于调用者给出的参数。

注意事项:

1、方法名相同

2、方法的参数类型,个数,顺序至少有一项不同

3、方法返回类型可以不同(只是返回类型不一样,不能构成重载)

4、方法的修饰符可以不同(只是控制访问修饰符不同,不能构成重载)


 

 

方法覆盖(override)

既然子类可以继承父类的属性和方法,这样可以提高代码的复用性,这个很好,可是问题来了,假设现在我要求大家写三个类猫猫,狗狗,猪猪。我们知道这三个东东都是动物,动物必然存在相同的特点。根据类的抽象特征,我们可以把它们的相同点提取出来,形成一个父类,然后继承。

x
1
//子类方法覆盖父类方法[Demo120.java]
2
public class Demo120{
3
    public static void main(String []args){
4
        //创建一只猫
5
        Cat cat1=new Cat();
6
            cat1.cry();
7
        Dog dog1=new Dog();
8
            dog1.cry();
9
    }
10
}
11
//动物类
12
class Animal{
13
    int age;
14
    String name;
15
    //都会叫
16
    public void cry(){
17
        System.out.println("我是动物,不知道怎么叫");
18
    }
19
 
20
}
21
//猫猫类
22
class Cat extends Animal{
23
    //覆盖父类方法
24
    public void cry(){
25
        System.out.println("猫猫叫!");
26
    }
27
}
28
//狗狗类
29
class Dog extends Animal{
30
    //覆盖父类方法
31
    public void cry(){
32
        System.out.println("汪汪叫!");
33
    }
34
}
JAVA入门到精通-第10讲-访问修饰符-重载-覆盖
   

方法覆盖(override)概念

简单的说:方法覆盖就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的那个方法。比如上个案例的Cat类中的cry方法就覆盖了Animal类的cry方法。

注意事项:

方法覆盖有很多条件,有些书上说的比较细,总的讲有两点一定注意:

1、子类的方法的返回类型,参数,方法名称,要和父类的返回类型,参数,方法名称完全一样,否则编译出错。

2、子类方法不能缩小父类方法的访问权限。

 

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

作业:上机实习题目

1Josephu问题(丢手帕问题)

Josephu问题为:设编号为1,2,...nn个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

    提示:用一个不带头结点的循环链表来处理Josephu问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点的人从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。

 
1
//Josephu问题(丢手帕问题)
2
//使用单向链表
3
public class Demo121 {
4
    public static void main(String[] args) {
5
        CycLink cyclink=new CycLink();
6
        cyclink.setLen(5);//链表长度
7
        cyclink.createLink();
8
        cyclink.setK(2);//从第几个人开始数
9
        cyclink.setM(2);//数几下
10
        cyclink.show();
11
        cyclink.play();
12
    }
13
}
14
 
15
class Child{
16
    int no;
17
    Child nextChild=null;
18
    public Child(int no){
19
        //给一个编号
20
        this.no=no;
21
    }
22
}
23
 
24
//单向环形链表
25
class CycLink{
26
    //先定义一个指向链表第一个小孩的引用
27
    //指向第一个小孩的引用,不能动
28
    Child firstChild=null;
29
    Child temp=null;
30
    int len=0;//表示共有多少个小孩
31
    int k=0;
32
    int m=0;
33
    //设置m数几下
34
    public void setM(int m){
35
        this.m=m;
36
    }
37
    //设置环形链表大小
38
    public void setLen(int len){
39
        this.len=len;
40
    }
41
    //设置从第几个人开始数数
42
    public void setK(int k){
43
        this.k=k;
44
    }
45
    //开始play
46
    public void play(){
47
        Child temp=this.firstChild;
48
        //1.先找到开始数数的人
49
        for(int i=1;i<k;i++){
50
            temp=temp.nextChild;
51
        }
52
        while(this.len!=1){
53
            //2.数m下
54
            for(int j=1;j<m;j++){
55
                temp=temp.nextChild;
56
            }
57
            //找到要出圈的前一个小孩
58
            Child temp2=temp;
59
            while(temp2.nextChild!=temp){
60
                temp2=temp2.nextChild;
61
            }
62
            //3.将数到m的小孩,退出圈
63
            temp2.nextChild=temp.nextChild;
64
            //让temp指向下一个数数的小孩
65
            temp=temp.nextChild;
66
            this.len--;
67
        }
68
        //最后一个小孩
69
        System.out.println("最后出圈的小孩:"+temp.no);
70
    }
71
   
72
    //初始化单向环形链表
73
    public void createLink(){
74
        for(int i=1;i<=len;i++){
75
            if(i==1){
76
                //创建第一个小孩
77
                Child ch=new Child(i);
78
                this.firstChild=ch;
79
                this.temp=ch;
80
            }else{
81
                //创建最后一个小孩
82
                if(i==len){
83
                    Child ch=new Child(i);
84
                    temp.nextChild=ch;
85
                    temp=ch;
86
                    temp.nextChild=this.firstChild;
87
                }else{
88
                    //继续创建小孩
89
                    Child ch=new Child(i);
90
                    temp.nextChild=ch;
91
                    temp=ch;   
92
                }
93
            }
94
        }
95
    }
96
    //打印该环形链表
97
    public void show(){
98
        //定义一个跑龙套
99
        Child temp=this.firstChild;
100
        do{
101
            System.out.print(temp.no+" ");
102
            temp=temp.nextChild;
103
        }while(temp!=this.firstChild);
104
    }
105
}