当前位置:   article > 正文

java(5):面向对象_经理与员工工资案例(利用多态实现)

经理与员工工资案例(利用多态实现)

5.1 面向对象的概念

一个对象有不同的属性,这些属性对应不同的方法

面向对象的三大特性:封装、继承、多态

封装性:一是指把对象的属性和行为看成是一个密不可分的整体,将这两者“封装”在一起(即封装在对象中);另外一层含义指“信息隐藏”,将不想让外界知道的信息隐藏起来。例如,驾校的学员学开车,只需要知道如何操作汽车,无需知道汽车内部是如何工作的。

继承性:描述类和类之间的关系,继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。

多态性:多态性指的是在一个类中定义的属性和方法被其它类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。不同的子类对同一种方法有不同的反应

示例代码:

  1. package llll;
  2. public class Student {
  3. String id;
  4. String name;
  5. int age;
  6. String address;
  7. public Student(String id,String name,int age,String address) {
  8. this.id = id;
  9. this.name = name;
  10. this.age = age;
  11. this.address = address;}
  12. public String getid() {
  13. return(this.id);}
  14. public void setid(String id) {
  15. this.id = id;}
  16. public String getname() {
  17. return(this.name);}
  18. public void setname(String name) {
  19. this.name = name;}
  20. public int getage() {
  21. return(this.age);}
  22. public void setage(int age) {
  23. this.age = age;}
  24. public String getaddress() {
  25. return(this.address);}
  26. public void setaddress(String address) {
  27. this.address = address;}
  28. }

5.2 类与对象

类表示某类群体的一些基本特征抽象,对象表示一个个具体的事物。

5.2.1 类的定义

(1)代码格式

class Student {    

String name;        // 定义String类型的变量name    

int age;            // 定义int类型的变量age    

String  sex;        // 定义String类型的变量sex     

// 定义 read () 方法     

void read() {           System.out.println("大家好,我是" + name + ",我在看书!");     } }

5.2.2 局部变量和成员变量

在方法中的变量时局部变量,在类下的变量是成员变量

5.2.3 对象的创建和使用

(1)创建

类名 对象名称 = new 类名();

例如:

 Student stu = new Student();

(2)使用

有两个,第一个给属性赋值:stu.name = '王俊凯';调用对象的方法:stu.read(),,就可以调用这个方法

5.2.4 访问控制

针对类、成员方法和属性,Java提供了4种访问控制权限

访问权限从小到大如下图所示:

(1)private 在本类中才可以访问

(2)default 在同一个包中可以访问

(3)protected 只能被本包及不同包的子类访问

(4)public 都可以

5.2.5 文件命名的要求

注意:如果一个Java源文件中定义的所有类都没有使用public修饰,那么这个Java源文件的文件名可以是一切合法的文件名;如果一个源文件中定义了一个public修饰的类,那么这个源文件的文件名必须与public修饰的类名相同。!!!!

5.3 实现封装

在类的外部不能实现对属性的赋值,对属性的赋值通过方法实现,这样就实现了封装性

(1)实现代码

有参的构造方法:

注意申明变量时前面不能写public了

  1. class Student{
  2. private String name;
  3. private int age;
  4. public Student(String n, int a) {
  5. this.name = n;
  6. this.age = a;
  7. }}

实例化对象时直接写成:

 Student stu = new Student("张三",18); 

如果要修改属性,使用stu.name = "李四",会失败。则如果父类中的属性都是private是,要定义修改方法:setname(),这样就可以在外部进行修改了。

注意:

在Java中的每个类都至少有一个构造方法,如果在一个类中没有定义构造方法,系统会自动为这个类创建一个默认的构造方法,这个默认的构造方法没有参数,方法体中没有任何代码,即什么也不做。

5.4 this关键字(构造方法中使用)

使用this关键字  区分成员变量与局部变量,为了避免出现下图的情况

只用在构造方法时用上!表示当前的变量的名字,即写成这种形式

5.5  static关键字(共享属性)

如果希望某些属性被所有对象共享,就必须将其声明为static属性。如果属性使用了static关键字进行修饰,则该属性可以直接使用类名称进行调用。

两个关键点:1、被static修饰的属性共享 2、被static修饰的方法的调用用类名 3、用static修饰代码块则只会运行一次

代码格式:

案例1:【对属性】A大学改名为B大学,将10万个学生的属性进行更改

  1. package four;
  2. import java.util.Scanner;
  3. public class Demo {
  4. public static void main(String[] args) {
  5. Student stu1 = new Student("张三",18);
  6. Student stu2 = new Student("王五",19);
  7. Student stu3 = new Student("李二",20);
  8. System.out.println(stu1.info());
  9. System.out.println(stu2.info());
  10. System.out.println(stu3.info());
  11. // System.out.println(stu.name);
  12. stu1.school = "B大学";
  13. System.out.println(stu1.info());
  14. System.out.println(stu2.info());
  15. System.out.println(stu3.info());
  16. }
  17. }

结果:

改了一个但是大家的大学都变了。

实例2:【对方法】

  1. public static String getSchool() {
  2. return school;
  3. public static void setSchool(String school) {
  4. Student.school = school;
  5. Student.setSchool("B大学");//这句实现全部更改

实例3:静态代码块【只被调用了一次】

  1. package four;
  2. public class Student {
  3. String name; //成员属性
  4. {
  5. System.out.println("我是构造代码块");
  6. }
  7. static {
  8. System.out.println("我是静态代码块");
  9. }
  10. public Student(){ //构造方法
  11. System.out.println("我是Student类的构造方法");
  12. }}

结果:

 5.6 继承的概念

子类继承父类的属性和方法,使得子类对象(实例)具有父类的特征和行为

  1. class 父类{
  2. ……
  3. }
  4. class 子类 extends 父类{
  5. ……
  6. }

直接继承: 

  1. //第一个
  2. public class Animal {
  3. private String name; // 定义name属性
  4. private int age; // 定义name属性
  5. public String getName() {
  6. return name;
  7. }
  8. public void setName(String name) {
  9. this.name = name;
  10. }
  11. public int getAge() {
  12. return age;
  13. }
  14. public void setAge(int age) {
  15. this.age = age;
  16. }
  17. }
  1. //第二个
  2. public class Dog extends Animal {
  3. //此处不写任何代码
  4. }
  1. //第三个
  2. public class Example01 {
  3. public static void main(String[] args) {
  4. Dog dog = new Dog(); // 创建一个Dog类的实例对象
  5. dog.setName("牧羊犬"); // 此时访问的方法时父类中的,子类中并没有定义
  6. dog.setAge(3); // 此时访问的方法时父类中的,子类中并没有定义
  7. System.out.println("名称:"+dog.getName()+",年龄:"+dog.getAge());
  8. }
  9. }

运行结果:

继承时加上自己的方法:

  1. // 定义Dog类继承Animal类
  2. class Dog extends Animal {
  3. private String color; // 定义name属性
  4. public String getColor() {
  5. return color;
  6. }
  7. public void setColor(String color) {
  8. this.color = color;
  9. }
  10. }
  1. public class Example01 {
  2. public static void main(String[] args) {
  3. Dog dog = new Dog(); // 创建一个Dog类的实例对象
  4. dog.setName("牧羊犬"); // 此时访问的方法时父类中的,子类中并没有定义
  5. dog.setAge(3); // 此时访问的方法时父类中的,子类中并没有定义
  6. dog.setColor("white");
  7. System.out.println("名称:"+dog.getName()+",年龄:"+dog.getAge()+",颜色:"+dog.getColor());
  8. }
  9. }

继承时需要注意的问题:

(1)在Java中,类只支持单继承,不允许多重继承。也就是说一个类只能有一个直接父类,例如下面这种情况是不合法的。

class A{} class B{}

class C extends A,B{}  // C类不可以同时继承A类和B类

(2)多个类可以继承一个父类,例如下面这种情况是允许的。

class A{}

class B extends A{}

class C extends A{}   // 类B和类C都可以继承类A

(3)在Java中,多层继承也是可以的,即一个类的父类可以再继承另外的父类。例如,C类继承自B类,而B类又可以继承自A类,这时,C类也可称作A类的子类。例如下面这种情况是允许的。

class A{}

class B extends A{}   // 类B继承类A,类B是类A的子类

class C extends B{}   // 类C继承类B,类C是类B的子类,同时也是类A的子类 

5.7 方法的重写 

直接覆盖掉注意权限的设定,新方法的权限不能比老方法的权限低

  1. // 定义Animal类
  2. class Animal {
  3. //定义动物叫的方法
  4. void shout() {
  5. System.out.println("动物发出叫声");
  6. }
  7. }
  8. // 定义Dog类继承动物类
  9. class Dog extends Animal {
  10. //重写父类Animal中的shout()方法
  11. void shout() {
  12. System.out.println("汪汪汪……");
  13. }
  14. }
  1. // 定义测试类
  2. public class Example03 {
  3. public static void main(String[] args) {
  4. Dog dog = new Dog(); // 创建Dog类的实例对象
  5. dog.shout(); // 调用dog重写的shout()方法
  6. }
  7. }

java代码只有有main才可以运行

5.8 super关键字(调用父类中被覆盖的方法)

用于调用父类中被覆盖的方法!

当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,Java提供了super关键字,super关键字可以在子类中调用父类的普通属性、方法以及构造方法。

具体用法:

接下来详细讲解super关键字的具体用法。 (1)使用super关键字访问父类的成员变量和成员方法,具体格式如下:

super.成员变量

super.成员方法(参数1,参数2…)

案例1:扩充父类中的方法【直接使用父类方法运行的结果】

  1. public String info() {
  2. return super.info()+",颜色:"+this.getColor();} //扩充父类中的方法

注意:通过super()调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次

5.9 final 关键字(不可继承)

Java中的类被final关键字修饰后,该类将不可以被继承,即不能够派生子类。

final class Animal {}

当一个类的方法被final关键字修饰后,这个类的子类将不能重写该方法。

Java中被final修饰的变量是为常量,常量只能在声明时被赋值一次,在后面的程序中,其值不能被改变。

final int AGE = 18;  

5.10  抽象类

类的行为特征不一致

5.10.1 抽象类定义

代码格式:

abstract class 抽象类名称{    

访问权限 返回值类型 方法名称(参数){            

return [返回值];     }    

访问权限 abstract 返回值类型 抽象方法名称(参数);     //抽象方法,无方法体 }

抽象类的定义规则如下:

(1)包含一个以上抽象方法的类必须是抽象类。

(2)抽象类和抽象方法都要使用abstract关键字声明。

(3)抽象方法只需声明而不需要实现。

(4)如果一个类继承了抽象类,那么该子类必须实现抽象类中的全部抽象方法。

注意:使用abstract关键字修饰的抽象方法不能使用private修饰,因为抽象方法必须被子类实现,如果使用了private声明,则子类无法实现该方法。

5.10.2 抽象方法定义

定义格式:abstract void 方法名称(参数);

  1. 1 // 定义抽象类Animal
  2. 2 abstract class Animal {
  3. 3 // 定义抽象方法shout()
  4. 4 abstract void shout();
  5. 5 }
  6. 6 // 定义Dog类继承抽象类Animal
  7. 7 class Dog extends Animal {
  8. 8 // 实现抽象方法shout()
  9. 9 void shout() {
  10. 10 System.out.println("汪汪...");
  11. 11 }
  12. 12 }
  13. 13 // 定义测试类
  14. 14 public class Example10 {
  15. 15 public static void main(String[] args) {
  16. 16 Dog dog = new Dog(); // 创建Dog类的实例对象
  17. 17 dog.shout(); // 调用dog对象的shout()方法
  18. 18 }
  19. 19 }

5.11 接口

如果一个抽象类的所有方法都是抽象的,则可以将这个类定义接口。接口是Java中最重要的概念之一,接口是一种特殊的类,由全局常量和公共的抽象方法组成,不能包含普通方法。

代码格式:

(1)接口定义和继承 代码格式:

方法没有返回对象就写 void!

public interface 接口名 extends 接口1,接口2... {

public static final 数据类型 常量名 = 常量值;     

public default 返回值类型 抽象方法名(参数列表);      

public abstract 返回值类型 方法名(参数列表);//没有方法体时这样写

public abstract 返回值类型 方法名(参数列表){         //默认方法的方法体      }      

public abstract 返回值类型方法名(参数列表){         //类方法的方法体      } }

注意:1、JDK 8对接口进行了重新定义,接口中除了抽象方法外,还可以有默认方法和静态方法(也叫类方法),默认方法使用default修饰,静态方法使用static修饰,且这两种方法都允许有方法体。

2、“extends 接口1,接口2...”表示一个接口可以有多个父接口,父接口之间使用逗号分隔。Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个接口可以同时继承多个父接口。

3、接口中的变量默认使用“public static final”进行修饰,即全局常量。接口中定义的方法默认使用“public abstract”进行修饰,即抽象方法。如果接口声明为public,则接口中的变量和方法全部为public。

4、不管写不写访问权限,接口中的方法访问权限永远是public。与此类似,在接口中定义常量时,可以省略前面的“public static final”,此时,接口会默认为常量添加“public static final”。

(2)定义类实现接口的功能 代码格式:

修饰符 class 类名 implements 接口1,接口2,...{

    ... }

注:类中的方法要将接口中的所有方法都写一遍

案例:

案例1:打印不同边长的正方形

  1. //创建接口
  2. package four;
  3. public interface MyPrint {
  4. public abstract void show();
  5. }
  1. //创建类实现接口
  2. package four;
  3. import java.util.Scanner;
  4. //创建类
  5. public class MyPrintSquare implements MyPrint {
  6. @Override
  7. public void show() {
  8. //重新改写void方法
  9. //创建scanner
  10. Scanner in = new Scanner(System.in);
  11. System.out.println("请输入一个数字");
  12. int a = in.nextInt(); //获取是多大的正方形后开始打印
  13. int i;
  14. int j;
  15. for (i=0;i<a;i++) {
  16. for (j=0;j<a;j++) {
  17. System.out.print("* ");
  18. }
  19. System.out.println();
  20. }
  21. }
  22. }
  1. //定义测试类
  2. package four;
  3. import java.util.Scanner;
  4. public class MyPrintTest {
  5. public static void main(String[] args) {
  6. MyPrintSquare n =new MyPrintSquare();
  7. n.show();
  8. //
  9. }
  10. }

运行结果:

5.12 多态概述

在Java中,多态是指不同对象在调用同一个方法时表现出的多种不同行为。

Java中多态主要有以下两种形式: (1)方法的重载。 (2)对象的多态性(方法重写)。

5.13 对象类型的转换

介绍:

父类转换成子类,或者子类转换成父类。比如Animal转换成Dog这种情况。

对象类型转换主要分为以下两种情况: (1)向上转型:子类对象→父类对象。 (2)向下转型:父类对象→子类对象。 对于向上转型,程序会自动完成,而向下转型时,必须指明要转型的子类类型。

代码格式:

对象向上转型:父类类型 父类对象 = 子类实例;

对象向下转型: 父类类型 父类对象 = 子类实例;

子类类型 子类对象 = (子类)父类对象;

向上转型:

  1. Dog dog = new Dog(); // 创建Dog对象
  2. Animal an = dog; //变成Animal了
  3. an.shout();

但是结果是:汪汪,还是狗叫,说明虽然是父类对象但是还是调用的子类的方法。

但是父类不能调用父类未定义的方法。

向下转型:

向下转型之前必须有向上转型!

  1. Animal an = new Dog(); // 此时发生了向上转型,子类→父类
  2. Dog dog = (Dog)an; // 此时发生了向下转型
  3. dog.shout();
  4. dog.eat();

结果:

5.14 instanceof关键字(判断对象是否某个类(或接口))

instanceof关键字判断一个对象是否是某个类(或接口)的实例

代码格式:

对象  instanceof类(或接口)

如果对象是指定的类的实例对象,则返回true,否则返回false。

a1 instanceof Animal

案例1:经理与员工工资案例

假设每次给员工涨工资一次能涨10,经理能涨20%。本案例要求利用多态实现给员工和经理涨工资。

  1. package com.itheima;
  2. abstract class Person{
  3. protected String name;
  4. protected String address;
  5. void setName(String name){
  6. this.name = name;
  7. }
  8. void setAddress(String address){
  9. this.address = address;
  10. }
  11. String getName(){
  12. return name;
  13. }
  14. String getAddress(){
  15. return address;
  16. }
  17. void add(int salary){
  18. }
  19. }
  20. class Employee extends Person{
  21. protected String number;
  22. protected double salary;
  23. protected int age;
  24. public Employee(){}
  25. public Employee(String name, String address, String number, double salary, int age){
  26. this.name = name;
  27. this.address = address;
  28. this.number = number;
  29. this.salary = salary;
  30. this.age = age;
  31. }
  32. void setNumber(String number)
  33. {
  34. this.number = number;
  35. }
  36. void setSalary(double salary)
  37. {
  38. this.salary = salary;
  39. }
  40. void setAge(int age)
  41. {
  42. this.age = age;
  43. }
  44. String getNumber(){
  45. return number;
  46. }
  47. double getSalary(){
  48. return salary;
  49. }
  50. int getAge(){
  51. return age;
  52. }
  53. void add()
  54. {
  55. this.salary *= 1.1;
  56. }
  57. }
  58. class Manager extends Employee{
  59. private String rank;
  60. public Manager(String name, String address, String number, double salary, int age, String rank){
  61. this.name = name;
  62. this.address = address;
  63. this.number = number;
  64. this.salary = salary;
  65. this.age = age;
  66. this.rank = rank;
  67. }
  68. void add() {
  69. this.salary *= 1.2;
  70. }
  71. void setRank(String rank){
  72. this.rank = rank;
  73. }
  74. String getRank(){
  75. return rank;
  76. }
  77. }
  78. public class Main{
  79. public static void main(String[] args){
  80. Employee worker = new Employee("张三","广东清远","9527",3000.0, 2);
  81. Manager manager1 = new Manager("李四","广东清远", "1122",10000.0,5,"高级经理");
  82. Manager manager2 = new Manager("王五","广东清远", "1100",8000.0,4,"经理");
  83. System.out.println("原有工资:");
  84. System.out.println("员工的工资:"+worker.getSalary());
  85. System.out.println("高级经理的工资:"+manager1.getSalary());
  86. System.out.println("经理的工资:"+manager2.getSalary());
  87. worker.add();
  88. manager1.add();
  89. manager2.add();
  90. System.out.println("涨工资后:");
  91. System.out.println("员工的工资:"+worker.getSalary());
  92. System.out.println("高级经理的工资:"+manager1.getSalary());
  93. System.out.println("经理的工资:"+manager2.getSalary());
  94. }
  95. }

5.15 Object关键字(所有类的父类)

每个类都直接或间接继承Object类,因此Object类通常被称之为超类。当定义一个类时,如果没有使用extends关键字为这个类显式地指定父类,那么该类会默认继承Object类。

常用方法:

也可以重写这些方法!

5.16 异常

5.16.1 try....catch

异常捕获:try...catch 需要经验,程序可以继续往下走

  1. public class Example25 {
  2. public static void main(String[] args) {
  3. //下面的代码定义了一个try…catch语句用于捕获异常
  4. try {
  5. int result = divide(4, 0); //调用divide()方法
  6. System.out.println(result);
  7. } catch (Exception e) { //对异常进行处理
  8. System.out.println("捕获的异常信息为:" + e.getMessage());
  9. }
  10. System.out.println("程序继续向下执行...");
  11. }

try...catch和finally

try有问题 进catch往下执行,遇到return执行但是finally必须执行。释放资源用于 释放堆内存,因为不会自己释放

  1. 1 public class Example26 {
  2. 2 public static void main(String[] args) {
  3. 3 //下面的代码定义了一个try…catch…finally语句用于捕获异常
  4. 4 try {
  5. 5 int result = divide(4, 0); //调用divide()方法
  6. 6 System.out.println(result);
  7. 7 } catch (Exception e) { //对捕获到的异常进行处理
  8. 8 System.out.println("捕获的异常信息为:" + e.getMessage());
  9. 9 return; //用于结束当前语句
  10. 10 } finally {
  11. 11 System.out.println("进入finally代码块");
  12. 12 }
  13. 13 System.out.println("程序继续向下执行…");
  14. 14 }
  15. 15 //下面的方法实现了两个整数相除
  16. 16 public static int divide(int x, int y) {
  17. 17 int result = x / y; //定义一个变量result记录两个数相除的结果
  18. 18 return result; //将结果返回
  19. 19 }
  20. 20 }

不论程序是发生异常还是使用return语句结束,finally中的语句都会执行。因此,在程序设计时,通常会使用finally代码块处理完成必须做的事情,如释放系统资源。

System.exit(0)表示退出当前的Java虚拟机,Java虚拟机停止了,任何代码都不能再执行了。

5.17 throws 关键字(遇到后续要重新编译!)

会经常那个遇到:!!!

并不知道别人编写的方法是否会发生异常。针对这种情况,Java允许在方法的后面使用throws关键字对外声明该方法有可能发生的异常,这样调用者在调用方法时,就明确地知道该方法有异常,并且必须在程序中对异常进行处理,否则编译无法通过。

包起来:

 

                                                                   

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/604313
推荐阅读
相关标签
  

闽ICP备14008679号