一:子类与父类:
在编写一个类时,若某个类中有所需要的成员变量和方法,如果我们想复用这个类中的成员和方法,那么可以将编写的类定义为这个类的子类,子类可以让我们不必一切“从头做起”。
继承是一种由已有的类创建新类的机制。利用继承,可以先定义一个共有属性的一半了in,根据该一般类再定义具有特殊属性的子类,子类继承一般类的属性和行为,并根据需要增加她自己新的属性和行为。
由继承得到的类称为子类,被继承的类称为父类(超类)。JAVA不支持多重继承,子类只能有一个父类,但父类可以有多个或者零个子类。
❶子类:在类的声明中,通过使用关键字extends来定义一个类的子类,格式为:
class 子类名 extends 父类名{
...
}
例如:
class people extends object{ //people为子类,object为父类
...
}
❷类的树形结构:
JAVA的类按继承关系形成树形结构(将类看作树上的结点).在这个树形结点中,根节点是object类,object是所有类的祖先。如果一个类的声明中没有使用extends关键字,这个类被系统默认为是Object的子类,即“class A”与“class A extends Object”是等同的。
public class People {
int age,leg = 2,hand = 2;
protected void showPeopleMess() {
System.out.printf("%d岁,%d只脚,%d只手\t",age,leg,hand);
}
}
public class Student extends People {
int number;
void tellNumber() {
System.out.printf("学号:%d\t",number);
}
int add(int x,int y) {
return x+y;
}
}
public class UniverStudent extends Student {
int multi(int x,int y) {
return x*y;
}
}
public static void main(String args[]) {
Student zhang = new Student();
zhang.age = 17; //访问继承的成员变量
zhang.number=100101;
zhang.showPeopleMess(); //调用继承的方法
zhang.tellNumber();
int x=9,y=29;
System.out.print("会做加法:");
int result=zhang.add(x,y);
System.out.printf("%d+%d=%d\n",x,y,result);
UniverStudent geng = new UniverStudent();
geng.age = 21; //访问继承的成员变量
geng.number=6609;
geng.showPeopleMess(); //调用继承的方法
geng.tellNumber(); //调用继承的方法
System.out.print("会做加法:");
result=geng.add(x,y); //调用继承的方法
System.out.printf("%d+%d=%d\t",x,y,result);
System.out.print("会做乘法:");
result=geng.multi(x,y);
System.out.printf("%d×%d=%d\n",x,y,result);
}
二:子类的继承性:
类可以有两种重要的成员:成员变量和方法。所谓子类继承父类的成员变量作为自己的一个成员变量,就像他们是在子类中被直接声明,可以被子类中自己定义的任何一种实例方法调用。如果子类中定义的实例方法不能操作父类的某个成员变量,该成员变量就没有被子类继承。
❶:子类和父类在同一包中的继承性:
如果子类和父类在同一个包中,那么子类自然的继承了父类中不是private的成员变量和方法作为自己的成员变量和方法。继承的成员变量或方法的访问权限保持不变。
❷:子类和父类不在同一包中的继承性:
当子类和父类不在同一包中时,子类只能继承父类中protected和public访问权限的成员变量作为子类的成员变量;同时,子类只能继承父类中的protected和public访问权限的方法作为子类的方法。
三:子类与对象:
❶子类对象的特点:
当用子类的构造方法创建一个子类的对象时,不仅子类中被声明的成员变量被分配了内存,而且父类的成员变量也被分配了内存空间,但只将其中的一部分,即子类继承的那部分成员变量,作为分配给子类对象的变量。子类不继承父类的私有变量。如果子类和父类不在同一包中,子类不继承父类的友好成员变量。
class People {
private int averHeight = 166;
public int getAverHeight() {
return averHeight;
}
}
class ChinaPeople extends People { //ChinaPeople是People 的子类,继承父类具有的方法和属性,相当于子类中一共有两个属性,三个方法;
int height;
public void setHeight(int h) {
height = h+averHeiht; // 非法,因为父类的averHeiht的访问权限是私有的;子类没有继承averHeiht
height = h;
}
public int getHeight() {
return height;
}
}
public static void main(String args[]) {
ChinaPeople zhangSan = new ChinaPeople();
System.out.println("子类对象未继承的averageHeight的值是:"+zhangSan.getAverHeight());
zhangSan.setHeight(178);
System.out.println("子类对象的实例变量height的值是:"+zhangSan.getHeight());
}
❷:关于instanceof运算符
instanceof运算符是JAVA独有的双目运算符,其左边的操作元是对象,右边的操作元是类。当左边的操作元是右边的类或者其子类所创建的对象时,instanceof运算符的结果是true,否则是false.。
四:成员变量的隐藏和方法重写:
❶成员变量的隐藏:在编写子类时,我们仍然可以声明成员变量,一种特殊的情况就是,所声明的成员变量的名字和从父类继承的成员变量的名字相同,在这种情况下,子类就会隐藏所继承的成员变量.
public class Goods {
public double weight;
public void oldSetWeight(double w) {
weight=w;
System.out.println("double型的weight="+weight);
}
public double oldGetPrice() {
double price = weight*10;
return price;
}
}
public class CheapGoods extends Goods {
public int weight;
public void newSetWeight(int w) {
weight=w;
// System.out.println("int型的weight="+weight);
}
public double newGetPrice() {
double price = weight*10;
return price;
}
}
public static void main(String args[]) {
CheapGoods cheapGoods=new CheapGoods();
//cheapGoods.weight=198.98; //是非法的,因为子类对象的weight已经是int型
cheapGoods.newSetWeight(198);
System.out.println("对象cheapGoods的weight的值是:"+cheapGoods.weight);
System.out.println("cheapGoods用子类新增的优惠方法计算价格:"+
cheapGoods.newGetPrice());
cheapGoods.oldSetWeight(198.987); //子类对象调用继承的方法操作隐藏的double型变量weight
System.out.println("cheapGoods使用继承的方法(无优惠)计算价格:"+
cheapGoods.oldGetPrice());
}
❷方法重写:
子类通过重写可以隐藏所继承的方法.
⑴重写的语法规则:
●子类中定义一个方法,这个方法的类型额父类的方法的类型一致或者是父类的方法的类型的子类;
●相同的方法名称,相同的参数列表.;二者必须同时满足。
⑵方法重写的目的:子类通过方法重写可以隐藏继承的方法,可以把父类的状态和行为改变为自身的状态和行为。
●如果父类的方法被子类继承,子类有权重写方法,子类若重写了父类的方法,就隐藏了继承的方法,那么子类对象调用方法一定调用的是子类重写的方法。
●如果子类没有重写,而是继承了父类的方法,那么子类创建的对象可以调用父类的方法,只不过子类方法产生的行为和父类的相同而已。
class A {
float computer(float x,float y) {
return x+y;
}
public int g(int x,int y) {
return x+y;
}
}
class B extends A {
float computer (float x,float y,double z) { //方法的重载,不是重写,因为参数列表不一样
return x-y;
}
}
public static void main(String args[]) {
B b=new B();
double result=b.computer(8,9); //b调用重写的方法
System.out.println(result);
int m=b.g(12,8); //b调用继承的方法
System.out.println(m);
}
⑶重写的注意事项:重写方法时,不允许降低方法的访问权限,但可以提高访问权限(访问权限从高到低的排列顺序:public、protected、友好的(一般默认不写)、private)。
class A{
protected float f(float x,float y){
return x-y;
}
}
class B extend A{
float f(float x,float y){ //非法,因为降低了访问权限
return x+y;
}
}
class C extends A{
public float f(float x,float y){ //合法,提高了访问权限
return x*y;
}
}
五:super关键字:
❶用super操作被隐藏的成员变量和方法:
子类隐藏了继承的成员变量或方法,则子类创建的对象就不在拥有该变量或方法,该变量或方法就归关键字super所拥有。因此,如果在子类中想使用被子类隐藏的成员变量或方法,就需要使用关键字super。例如super.x、super.A()就是访问和调用被子类隐藏的成员变量x和方法 A()。
例如:
class Sum {
int n;
float f() {
float sum=0;
for(int i=1;i<=n;i++){ //1:循环变量初始化i=1;2判断循环条件i<=n
sum=sum+i;
}
return sum;
}
}
class Average extends Sum {
int n; //100
float f() {
float c;
super.n=n; //访问父类中被隐藏的属性n
c=super.f(); //调用父类中被子类重写的方法f
return c/n;
}
float g() {
float c;
c=super.f();
return c/2;
}
}
public class {
public static void main(String args[]) {
Average aver=new Average();
aver.n=100;
float resultTwo=aver.g();
float resultOne=aver.f();
System.out.println("resultOne="+resultOne);
System.out.println("resultTwo="+resultTwo);
}
}
❷使用super调用父类的构造方法:
如果子类的构造方法没有指明使用父类的那个构造方法,子类就调用父类不带参数的构造方法。
由于子类不继承父类的构造方法,因此,子类在其构造方法中需使用super来调用父类的构造方法,而且super必须是子类构造方法中的头一条语句。
六:final关键字:finai关键字可以修饰类、成员变量和方法中的局部变量。
❶final类:可以使用final将类声明为final类。final类不能被继承,即不能有子类。
❷final方法:如果用final修饰父类中的一个方法,那么这个方法不允许被子类重写。
❸常量:如果成员变量或局部变量被修饰为final,那么他就是常量。由于常量在进行期间不允许再发生变化,所以常量在声明时没有默认值,要求程序在声明常量时指定常量的值。例如:
final class A { //final类不能被继承
final double PI=3.1415926; // final修饰的变量就成为了常量,常量通常用大写,PI是常量
public double getArea(final double r) {
return PI*r*r;
}
public final void speak() { //final修改的方法不能被子类重写
System.out.println("您好,How's everything here ?");
}
}
public class {
public static void main(String args[]) {
A a=new A();
System.out.println("面积:"+a.getArea(100));
a.speak();
}
}
七:对象的上转型对象:
❶老虎虽是动物,但如果说老虎是动物时,就是去了老虎独有的属性和功能。假设Animal类是Tiger类的父类,当用子类创建一个对象。并把这个对象的引用放到父类的对象中时,
Animal a;
Tiger b=new tiger();
a=b;
称对象a是对象b的上转型对象。
上转型对象的特点:
❶上转型对象不能操作子类新增的成员变量,不能调用子类新增的成员方法;
❷上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。
八:继承与多态:
多态就是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为。
例如下列展示多态的例子:
class 动物 {
void cry() {
System.out.println("haha");
}
}
class 狗 extends 动物 {
void cry() {
System.out.println("汪汪.....");
}
}
class 猫 extends 动物 {
void cry() {
System.out.println("喵喵.....");
}
}
public class {
public static void main(String args[]) {
动物 animal;
animal = new 狗();
animal.cry();
animal=new 猫();
animal.cry();
}
九:abstract类和abstract方法
用关键字abstract修饰的类称为abstract类(抽象类)e.g
abstract class A{
...
}
用关键字abstract修饰的方法称为abstract方法(抽象类)e.g
abstract int min(int x,int y);
abstrat方法的规则:
❶只允许声明,没有方法体;
❷不允许使用final和abstract同时修饰一个方法或类;
❸不允许使用static修饰abstract方法(即abstract方法必须是实例方法)
十: 案例
群主发普通红包:
1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
2. 成员领取红包后,保存到成员余额中。
请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。