Java 基础--07继承、super、this、抽象类

继承
定义:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接 访问父类中的非私有的属性和行为。
继承的格式:通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

class 父类 {
 ... 
 }
 class 子类 extends 父类 { 
 ... 
 }

如果子类父类中出现重名的成员变量,这时的访问是有影响的
如下

     class Fu {
      // Fu中的成员变量。 
      int num = 5; 
      }
      class Zi extends Fu { 
      // Zi中的成员变量 
      int num = 6; 
      public void show() {
       // 访问父类中的num 
       System.out.println("Fu num=" + num); 
       // 访问子类中的num 
       System.out.println("Zi num=" + num); 
       } 
       }
       class ExtendsDemo03 { public static void main(String[] args) { 
       // 创建子类对象 
       Zi z = new Zi(); 
       // 调用子类中的show方法
       z.show();
        } }
        演示结果:
         Fu num = 6 
        Zi num = 6

子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super 关键字,修饰 父类成员变量,类似于之前学过的 this
如下

  class Zi extends Fu {
   // Zi中的成员变量
    int num = 6;
     public void show() {
      //访问父类中的num
       System.out.println("Fu num=" + super.num); 
       //访问子类中的num 
       System.out.println("Zi num=" + this.num); 
       } }
       演示结果: 
       Fu num = 5 
       Zi num = 6

使用格式:
super.父类成员变量名
成员方法不重名
如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对 应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。代码如下:

class Fu{
 public void show(){ 
 System.out.println("Fu类中的show方法执行"); 
 		}
  }
  class Zi extends Fu{
   public void show2(){ 
   System.out.println("Zi类中的show2方法执行");
    	} 
    }
    public class ExtendsDemo04{ 
    public static void main(String[] args) { 
    Zi z = new Zi();
     //子类中没有show方法,但是可以找到父类方法去执行
     z.show();
      z.show2();
      		}
       }

成员方法重名——重写(Override) 如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。声明不变,重新实现
代码如下

    class Fu { public void show() { 
    System.out.println("Fu show");
     } }
     class Zi extends Fu { 
     //子类重写了父类的show方法
      public void show() { 
      System.out.println("Zi show"); 
      } }
      public class ExtendsDemo05{ 
      public static void main(String[] args) { 
      Zi z = new Zi();
       // 子类中有show方法,只执行重写后的show方法 
       z.show();
        // Zi show } }

重写方法,可以对方法进行增强,可以定义自己的行为,也能继承父类的功能
super和this的含义
super:代表父类的存储空间标识,可以理解为父类的引用
this:代表当前对象的引用,谁调用就代表谁
java只支持单继承,不支持多继承
抽象类
定义:父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有 意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法 的类就是抽象类。
抽象方法 : 没有方法体的方法。
抽象类:包含抽象方法的类
abstract使用格式
使用abstract修饰的方法,就是抽象方法,抽象方法只有方法名,没有方法体
定义格式:
修饰符 abstract 返回值类型 方法名 (参数列表)
例如

		     public abstract void run();

抽象类
如果一个类包括了抽象方法,那么该类必须是抽象类
定义格式: abstract class 类名字{
}
例如

  public abstract class Animal {
   public abstract void run(); 
   }

抽象的使用:继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父 类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。
注意
1、抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
2、抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
3、 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
4、抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象 类。
继承的综合案例
群主发普通红包
群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则: 1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。 2. 成员领取红包后,保存到成员余额中。 请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。

定义用户类
	  
	  public class User { 
	  // 成员变量 
	  private String username;// 用户名
	   private double leftMoney;// 余额 
	   // 构造方法
	   public User() {
	    } 
	    public User(String username, double leftMoney) { 
	    this.username = username; 
	    this.leftMoney = leftMoney; 
	    }
	    // get/set方法 
	    public String getUsername() {
	     return username;
	     }
	     public void setUsername(String username) {
	      this.username = username; 
	      }
	      public double getLeftMoney() { 
	      return leftMoney; 
	      }
	      public void setLeftMoney(double leftMoney) {
	       this.leftMoney = leftMoney; }
	       // 展示信息的方法 
	       public void show() { 
	       System.out.println("用户名:"+ username +" , 余额为:" +
	       leftMoney + "元"); 
	      	 	}
	       	 }
	       	 定义群主类:
	       	 public class QunZhu extends User {
	       	  // 添加构造方法 
	       	  public QunZhu() {
	       	   }
	       	   public QunZhu(String username, double leftMoney) { 
	       	   // 通过super 调用父类构造方法 
	       	   super(username, leftMoney);
	       	    }
	       	   /* 群主发红包,就是把一个整数的金额,分层若干等
	       	   份。
	       	    1.获取群主余额,是否够发红包. 不能则返回null,并提示. 
	       	    能则继续. 
	       	    2.修改群主余额. 
	       	    3.拆分红包. 
	       	    3.1.如果能整除,那么就平均分。
	       	     3.2.如果不能整除,那么就把余数分给最后一份。 */ 
	       	     public ArrayList<Double> send(int money, int count) {
	       	      // 获取群主余额
	       	      double leftMoney = getLeftMoney();
	       	       if(money > leftMoney) {
	       	       return null;
	       	        }
	       	       // 修改群主余额的 
	       	       setLeftMoney(leftMoney ‐ money);
	       	        // 创建一个集合,保存等份金额 
	       	        ArrayList<Double> list = new ArrayList<>(); 
	       	        // 扩大100倍,相当于折算成'分'为单位,避免小数运算
	       	        损失精度的问题 
	       	        money = money * 100; 
	       	        // 每份的金额 
	       	        int m = money / count;
	       	        // 不能整除的余数 
	       	        int l = money % count; 
	       	        // 无论是否整除,n‐1份,都是每份的等额金额 
	       	        for (int i = 0; i < count ‐ 1; i++) {
	       	         // 缩小100倍,折算成 '元'
	       	          list.add(m / 100.0);
	       	          }// 判断是否整除
	       	          if (l == 0) { 
	       	          // 能整除, 最后一份金额,与之前每份金额一致
	       	         list.add(m / 100.0);
	       	          } else { 
	       	            // 不能整除, 最后一份的金额,是之前每份金额+余
	       	            数金额 
	       	          list.add((m + l) / 100.00);
	       	            }
	       	            // 返回集合 
	       	          return list; 
	       	            	} 
	       	            }
	       定义成员类:
	       public class Member extends User { public Member() { 
	       }public Member(String username, double leftMoney) { 
	       super(username, leftMoney); 
	       }
	       // 打开红包,就是从集合中,随机取出一份,保存到自己的余
	       额中 
	       public void openHongbao(ArrayList<Double> list) {
	        // 创建Random对象 
	       Random r = new Random();
	         // 随机生成一个角标 
	       int index = r.nextInt(list.size());
	          // 移除一个金额
	       Double money = list.remove(index); 
	          // 直接调用父类方法,设置到余额 
	       setLeftMoney( money ); 
	          		}
	           }
定义测试类:
	       
public class Test { public static void main(String[] args) {
 // 创建一个群主对象 
	 QunZhu qz = new QunZhu("群主" , 200);
	 // 创建一个键盘录入 
	   Scanner sc = new Scanner(); 
	  System.out.println("请输入金额:");
	   int money = sc.nextInt(); 
	  System.out.println("请输入个数:");
	 int count = sc.nextInt(); 
	  // 发送红包 
	 ArrayList<Double> sendList = s.send(money,count); 
	  // 判断,如果余额不足 
	   if(sendList == null){ 
	 System.out.println(" 余额不足...");
	  return;
	             }
	             // 创建三个成员 
	           Member m = new Member(); 
	           Member m2 = new Member();
	           Member m3 = new Member(); 
	              // 打开红包 
	           m.openHongbao(sendList);
	           m2.openHongbao(sendList);
	           m3.openHongbao(sendList);
	                 // 展示信息 
	            qz.show(); 
	            m.show(); 
	            m2.show();
	            m3.show();
	                 	  }
	                    }
发布了16 篇原创文章 · 获赞 10 · 访问量 535

猜你喜欢

转载自blog.csdn.net/qq_44872781/article/details/104523797