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





























继承--为什么有?[Demo117.java]
//功能:说明继承的重要性
x
package com.abc;//包名public class Demo117 { public static void main(String[] args) { Pupil p1=new Pupil(); p1.printName(); }} //将学生的共有属性提取,做一个父类class Stu{ //定义成员属性 protected int age; public String name; public float fee; private String job;//私有将不被继承 //编程中,如果你不希望子类继承某个属性或方法 //则将其声明为private即可 public void printName(){ System.out.println("名字"+this.name); }} //小学生类class Pupil extends Stu{ //交学费 public void pay(float fee){ this.fee=fee; }}//幼儿class Pre extends Pupil{ //交学费 public void pay(float fee){ this.fee=fee*1.5f; }}//中学生类class MiddleStu extends Stu{ //交学费 public void pay(float fee){ this.fee=fee*0.8f; }}//大学生类class ColStu extends Stu{ //交学费 public void pay(float fee){ this.fee=fee*0.1f; }}继承--解决之道
继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类(比如刚才的Student),在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends语句来声明继承父类:
语法:class 子类 extends 父类
这样,子类就会自动拥有父类定义的某些属性和方法。
继承--深入讨论
1、父类的哪些属性(变量)、方法被子类继承了?并不是父类的所有属性、方法都可以被子类继承
父类 子类
public 属性; public
属性;
protected 属性; 继承 protected 属性;
private 属性; → 属性;
属性;
public 方法; public
方法;
protected 方法; protected
方法;
private 方法; 方法;
方法;
2、结论
从图可以看出,父类的public修饰符的属性和方法;protected修饰符的属性和方法;默认修饰符属性和方法被子类继承了,父类的private修饰符的属性和方法不能被子类继承。
继承--注意事项
1、子类最多只能继承一个父类(指直接继承)
2、java所有类都是Object类的子类 (所有的子类都可以逐级继承,例:爷->父->子->孙)
3、JDK6中有202个包3777个类、接口、异常、枚举、注释和错误
4、在做开发的时候,强烈建议大家多查jdk帮助文档
5、在使用类时,实在不知道怎么办,多使用搜索引擎
定义类的改进
在提出包后,我们类的定义就更加完善了:
class 类名{ class 类名{ class类名{ package包名;
成员变量; → 成员变量; → 成员变量; → class 类名{
} 成员方法; 构造方法; 成员变量;
} 成员方法; 构造方法;
} 成员方法;
} ↓
↓←←←←←←←←←←←←←←←←←←←←←←←←←
package 包名;
class 类名 extends 父类{ 待定
成员变量; → ....
构造方法;
成员方法;
}
-------------------------------------------------------------------------------
java面向对象编程(2)--方法重载(overload)
方法重载(overload)
按顺序,我们应该讲解多态,但是在讲解多态前,我们必须讲解方法重载和方法覆盖(override)。
请编写一个类(Abc),编写方法可以接收两个整数,返回两个数中较大的数[Demo119.java]
x
//方法重载(overload)getMaxpublic class Demo119{ public static void main(String []args){ Abc2 abc1=new Abc2(); System.out.println(abc1.getMax(12,14)); System.out.println(abc1.getMax(24f,20f)); }} class Abc2{ //返回较大的整数 public int getMax(int i,int j){ if(i>j){ return i; }else{ return j; } } public float getMax(float a,float b){ if(a>b){ return a; }else{ return b; } } //如果只是返回类型不一样,能否构成重载?不能够构成重载/* public double getMax(float d,double c){ if(c>d){ return c; }else{ return d; } } //如果只是控制访问修饰符不同,能否构成重载?不能够构成重载 protected float getMax(float c,float d){ if(c>d){ return c; }else{ return d; } }*/}方法重载(overload)概念
简单的说:方法重载就是在类的同一种功能的多种实现方式,到底采用哪种方式,取决于调用者给出的参数。
注意事项:
1、方法名相同
2、方法的参数类型,个数,顺序至少有一项不同
3、方法返回类型可以不同(只是返回类型不一样,不能构成重载)
4、方法的修饰符可以不同(只是控制访问修饰符不同,不能构成重载)
方法覆盖(override)
既然子类可以继承父类的属性和方法,这样可以提高代码的复用性,这个很好,可是问题来了,假设现在我要求大家写三个类猫猫,狗狗,猪猪。我们知道这三个东东都是动物,动物必然存在相同的特点。根据类的抽象特征,我们可以把它们的相同点提取出来,形成一个父类,然后继承。
x
//子类方法覆盖父类方法[Demo120.java]public class Demo120{ public static void main(String []args){ //创建一只猫 Cat cat1=new Cat(); cat1.cry(); Dog dog1=new Dog(); dog1.cry(); }}//动物类class Animal{ int age; String name; //都会叫 public void cry(){ System.out.println("我是动物,不知道怎么叫"); } }//猫猫类class Cat extends Animal{ //覆盖父类方法 public void cry(){ System.out.println("猫猫叫!"); }}//狗狗类class Dog extends Animal{ //覆盖父类方法 public void cry(){ System.out.println("汪汪叫!"); }}
方法覆盖(override)概念
简单的说:方法覆盖就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的那个方法。比如上个案例的Cat类中的cry方法就覆盖了Animal类的cry方法。
注意事项:
方法覆盖有很多条件,有些书上说的比较细,总的讲有两点一定注意:
1、子类的方法的返回类型,参数,方法名称,要和父类的返回类型,参数,方法名称完全一样,否则编译出错。
2、子类方法不能缩小父类方法的访问权限。
===============================================================================
作业:上机实习题目
1、Josephu问题(丢手帕问题)
Josephu问题为:设编号为1,2,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
提示:用一个不带头结点的循环链表来处理Josephu问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点的人从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。
//Josephu问题(丢手帕问题)//使用单向链表public class Demo121 { public static void main(String[] args) { CycLink cyclink=new CycLink(); cyclink.setLen(5);//链表长度 cyclink.createLink(); cyclink.setK(2);//从第几个人开始数 cyclink.setM(2);//数几下 cyclink.show(); cyclink.play(); }} class Child{ int no; Child nextChild=null; public Child(int no){ //给一个编号 this.no=no; }} //单向环形链表class CycLink{ //先定义一个指向链表第一个小孩的引用 //指向第一个小孩的引用,不能动 Child firstChild=null; Child temp=null; int len=0;//表示共有多少个小孩 int k=0; int m=0; //设置m数几下 public void setM(int m){ this.m=m; } //设置环形链表大小 public void setLen(int len){ this.len=len; } //设置从第几个人开始数数 public void setK(int k){ this.k=k; } //开始play public void play(){ Child temp=this.firstChild; //1.先找到开始数数的人 for(int i=1;i<k;i++){ temp=temp.nextChild; } while(this.len!=1){ //2.数m下 for(int j=1;j<m;j++){ temp=temp.nextChild; } //找到要出圈的前一个小孩 Child temp2=temp; while(temp2.nextChild!=temp){ temp2=temp2.nextChild; } //3.将数到m的小孩,退出圈 temp2.nextChild=temp.nextChild; //让temp指向下一个数数的小孩 temp=temp.nextChild; this.len--; } //最后一个小孩 System.out.println("最后出圈的小孩:"+temp.no); } //初始化单向环形链表 public void createLink(){ for(int i=1;i<=len;i++){ if(i==1){ //创建第一个小孩 Child ch=new Child(i); this.firstChild=ch; this.temp=ch; }else{ //创建最后一个小孩 if(i==len){ Child ch=new Child(i); temp.nextChild=ch; temp=ch; temp.nextChild=this.firstChild; }else{ //继续创建小孩 Child ch=new Child(i); temp.nextChild=ch; temp=ch; } } } } //打印该环形链表 public void show(){ //定义一个跑龙套 Child temp=this.firstChild; do{ System.out.print(temp.no+" "); temp=temp.nextChild; }while(temp!=this.firstChild); }}
浙公网安备 33010602011771号