Java学习笔记4

 
======================================================================
java
第四天
======================================================================
高内聚( independence : 一个对象独立 [ 注意独立 , 不要其他对象的帮助 ] 完成一个工作 .
======================================================================
(1)
封装(encapsulation): 该隐藏的隐藏 , 该公开的公开 . 属性 (property)[ 隐藏 ], 方法 [ 公开 ( 有些公开 , 有些隐藏 .)].// 给自己用的方法私有 , 给别人用的方法公开 . // 公开声明 , 隐藏实现 .[ 只修改实现这样对架构的影响最小 .] 封装和弱藕合有关系
======================================================================
(2)
继承(inheritance): 共性写在父类 , 个性 (individual) 写在子类 . // 单继承是 java 简单性的表现 . java 中的 , 父类的私有属性不继承到子类中 . 子类中 . 创建子对象要先创建一个父类 , 然后在加上一个子类对象 [ 子类对象 = 父类对象 + 子类对象独特的地方 ]. 子类里边有父类和子类 . 子类能不能访问
单继承的好处 : 类和类成为树状关系 , 不是网状结构 .[java 简单性的体现,但是能通过接口来实现多继承 ]
private : 不能继承 .( 但是子类里边有这个属性 , 如果修饰方法 , 子类就不能用了 , 属性的话 , 还能用一下 .)
default : 同包子类能继承 , 不同包子类不能继承 .
protected : 同包或者不同包的子类 .
public : 任何类型 :
protected: 的特殊使用方法如下:
package
b;
import a.*;
class TestProteced {
       public static void main(String[] args) {
              B b = new B();
              b.m(); // 只有在子类的内部才能用父类的 protected 属性和方法 . 在即使是子类的对象外部使用也不行 .
       }
}
class B extends A {
       void mm() {
              m(); // 在子类内部可以使用父类中 protected 属性和方法 .
       }
}
package a;
class A{
       void m(); // 外包中的方法 .
}
(3) 多态(polymorphism):方法覆盖: override //父子类才发生覆盖.方法名相同,参数表相同,返回值也要相同.修饰符可以不同[权限要越来越大[严->宽]] //1.4 中以上对
多态: 一个行为在不同的环境下有不同的行为方式.
多态分为:编译时多态[方法重载],和运行时多态.
//5.0: 不强制返回值一样(两个类必需)也可以返回类型的子类;
 
class Animanl{
       int a =10;
       protected A eat(){  // B A 的子类 .
              System. out .println( "hehe" );
              return null ;
       }
}
class Dog extends Animanl{
       int a=10;  // 属性的遮盖 .(shadow)
       super .a=1;  // 要访问父类中的属性或者方法 . super 关键字 .
       super .eat(); // 调用父类的方法 .
       protected B eat(){  // jdk 5.0 中返回值可以不同 , 有条件就是返回值可以是覆盖对象返回值的子类 .
              System. out .println();
              return null ;
       }
}
(3) 构造一个对象的过程:
一个对象的构造过程:
1.分配空间,
2.初始化属性
3.调用构造方法.
(4) 有父类的构造过程:有父类的类:
1. 递归的构造父类对象.//父类可能还有父类.
2. 分配本类的空间.
3. 初始化本类的属性.
4. 调用本类的构造方法.
//如果不想记那么多构造方法的语法,那么最好在每个类加上无参的构造方法.
有父类的类的构造方法例子:
---------------------------------------------
package test;
class Test{
       public static void main(String[] args){
              int a=10;
              ClassB b= new ClassB(a); // 结果是 : ClassA() ClassB(int )
       }     
}
class ClassA{
       public ClassA(){
              System. out .println( "ClassA()" );
       }
}
class ClassB{
       ClassB( int a){
              System. out .println( "ClassA(int )" );
       }
}
class ClassC{
       public ClassC(){
              System. out .println( "ClassB()" );
       }
}
class ClassD{
      // super(a); // 如果
       ClassD( int a){
              System. out .println( "ClassD(int a)" );
       }
}
一个构造方法,如果不写,默认是super(), 既父类的无参构造方法.
class A{
       /*
       public A(){
              super();
       }
        */   默认的产生 [ 父类的无参构造方法 ].
}
===============================
package test;
 
class Super {
       //Super(){}
       public Super( int a) {
       }
}
 
class Sub extends Super {
       public Sub( int a) {
              super (a);
       } // 如果父类写了有参的构造方法 , 子类必需写一个有参的构造方法来构造父类。
}
如果在子类中有一个方法,这个方法方法名相同,参数表不同,叫作方法重载.
======================================================================
(5) 多态(polymorphism):Animal                    a=      new Dog();
编译时类型(引用类型)        运行时类型
主观(把它看成什么)            客观
3条原则:
 <1> 对象运行时类型不变.
 <2> 只能对一个引用调用其编译时类型定义的方法.  //对象只能调用父类中定义的方法.
 <3> 运行的时候,会根据运行时类型找,覆盖之后的方法. //
例子:
VCD,DVD机的例子:
遥控器()
package test;
public class TestPoly {
       public static void main(String[] args) {
              Animal a = new Dog();
              a.eat();
              a.sleep();
              // a.call();
              Dog d;
              d = a; // 语法错误 , 不兼容类型 .cannot convert        
              d = (Dog) a; // 要把 a Dog .
              liucy l = new liucy(); // 不可以转换 , 不可能成功 .
              Animal b = new Cat();
              Dog c;
              c = (Dog) b; // 编译时不出错 , 但是运行时会出异常 : ClassCastException; 类型转换失败 ;
              // 非要把 b 当狗看。
       }
}
class liucy {
}
class Dog extends Animal {
       void eat() {
       }
       void sleep() {
              System. out .println( " 狗睡觉!! " );
       }
       void call() {
              System. out .println( " 狗叫!! wang wang " );
       }
}
class Cat extends Animal {
       void eat() {
       }
       void sleep() {
              System. out .println( " 猫睡觉!! " );
       }
       void call() {
              System. out .println( " 猫叫!! miao ~~miao~~~~ " );
       }
}
(6) 判断两个类型是否相同.引用     instanceof();    类名
a            "是不是"       Dog
//判断引用的对象是否兼容. //用在强制类型转换之前.
System.out.println(a instanceof Dog); true;
System.out.println(a instanceof Cat); false ;
System.out.println(a instanceof Animal); true ;
强制类型转换: 当我们把父类的引用赋值给子类引用的时候,需要强制类型转换,
多态的作用: 屏蔽不同子类的差异.
======================================================================
作业:
1.设计一个形状类,方法:求周长和求面积
 形状类的子类:Rect(矩形),Circle(圆形)
 Rect类的子类:Square(正方形)
 不同的子类会有不同的计算周长和面积的方法
 创建三个不同的形状对象,放在Shape类型的数组里,分别打印出每个对象的周长和面积
总结:这个题目有写基础,没有代表性,也就不把代码写上去了,呵呵.
======================================================================
2.某公司的雇员分为以下若干类:
Employee:这是所有员工总的父类,属性:员工的姓名,员工的生日月份。方法:getSalary(int month) 根据参数月份来确定工资,如果该月员工过生日,则公司会额外奖励100元。
SalariedEmployee:Employee的子类,拿固定工资的员工。属性:月薪
HourlyEmployee:Employee的子类,按小时拿工资的员工,每月工作超出160小时的部分按照1.5倍工资发放。属性:每小时的工资、每月工作的小时数
SalesEmployee:Employee的子类,销售人员,工资由月销售额和提成率决定。属性:月销售额、提成率
BasePlusSalesEmployee:SalesEmployee的子类,有固定底薪的销售人员,工资由底薪加上销售提成部分。属性:底薪。
写一个程序,把若干各种类型的员工放在一个Employee数组里,写一个函数,打印出某月每个员工的工资数额。注意:要求把每个类都做成完全封装,不允许非私有化属性。
package test;
 
public class TestEmployee {
       public static void main(String[] args) {
              Employee[] a = new Employee[4];
              a[0] = new SalariedEmployee( " 陈鹏烨 " , 12, 10000);
              a[1] = new HourlyEmployee( " 陈宗权 " , 10, 100, 300);
              a[2] = new SalesEmployee( " 小企鹅 " , 3, 100000, 0.05);
              a[3] = new BasePlusSalesEmployee( " 杨清 " , 10, 10000, 0.2, 5000);
              for ( int i = 0; i < a. length ; i++) {
                     System. out .println(a[i].getName() + " 工资是 : " + a[i].getSalary(10));
              }
       }
}
 
// 雇员类 , 是所有雇员的父类 . 把共性全部写在父类里边 .
// 分析 ---> 共性有 : 姓名 , 生日 ;
class Employee {
       private String name ;
 
       private int birthday ;
 
       Employee() {
       }
 
       // 有参构造方法 , 用来构造父类 .
       Employee(String name, int birthday) {
              this . name = name;
              this . birthday = birthday;
       }
 
       // 也是所有雇员的共性 , 每个雇员都会在生日的时候得到 100 元钱 .
       double getSalary( int month) {
              if (month == birthday ) {
                     return 100;
              }
              return 0;
       }
 
       // 用来获得雇员的姓名 :
       String getName() {
              return name ;
       }
}
 
// 雇员类的子类 ,
class SalariedEmployee extends Employee {
       private int monthsalary ; // 自己私有的属性 , 每个月的基本工资 .
 
       SalariedEmployee() {
       } // 无参构造函数 , 记住最好写上 .
       // 有参构造函数 ;
 
       SalariedEmployee(String name, int birthday, int monthsalary) {
              super (name, birthday); // 用来初始化 , 父类的的公有的属性 .
              this . monthsalary = monthsalary; // 初始化子类的属性 .
       }
 
       // 覆盖了父类的获得工资的方法 . 因为每类员工都有不同的工资方法 .
       double getSalary( int month) {
              return super .getSalary(month) + monthsalary ; // 生日的钱 + 基本工资 ;
       }
}
 
// 雇员类的子类 , 小时工 .
class HourlyEmployee extends Employee {
       // 自己私有的属性 . 每小时的工钱 , 和工作的小时数 .
       private int hoursalary ;
 
       private int hour ;
 
       HourlyEmployee() {
       }
 
       // 有参构造函数 , 有来初始化自己私有的属性和父类中的属性 .
       HourlyEmployee(String name, int birthday, int hoursalary, int hour) {
              super (name, birthday); // 初始化公有的属性 .
              this . hoursalary = hoursalary; // 初始化私有的属性 .
              this . hour = hour;
       }
 
       // 覆盖父类中获得工资的方法 ,
       double getSalary( int month) {
              double m = 0;
              if ( hour >= 160) {
                     return super .getSalary(month) + hoursalary * 160 + 1.5 * hoursalary
                                   * ( hour - 160); // 生日的钱 + 小时 * 每小时的工资 ;
              } else
                     return super .getSalary(month) + hoursalary * hour ; // 生日的钱 + 小时 * 每小时的工资 ;
       }
}
 
// 雇员类的子类 :
class SalesEmployee extends Employee {
       // 自己私有的属性 : 销售额 , 提成率 ;
       private int sale ;
 
       private double rate ;
 
       SalesEmployee() {
       }
 
       // 有参构造函数 , 初始化类 .
       SalesEmployee(String name, int birthday, int sale, double rate) {
              super (name, birthday); // 公有属性 ;
              this . sale = sale; // 私有属性 ;
              this . rate = rate;
       }
 
       // 覆盖了父类的获得工资的方法 .
       double getSalary( int month) {
              return super .getSalary(month) + sale * rate ; // 生日的钱 + 提成 ;
       }
}
 
// SalesEmployee 的子类 , 继承了 SalesEmployee 的所有属性 .
class BasePlusSalesEmployee extends SalesEmployee {
       // 本类私有的属性 : 底薪 . 其他全部继承子父类 .
       private int basesalary ;
 
       BasePlusSalesEmployee() {
       }
 
       BasePlusSalesEmployee(String name, int birthday, int sale, double rate,
                     int basesalary) {
              super (name, birthday, sale, rate); // 初始化 , 和父类相同的属性
              this . basesalary = basesalary; // 初始化自己的属性 ;
       }
 
       // 覆盖了父类的获得薪水的方法 .
       double getSalary( int month) {
              return super .getSalary(month) + basesalary ; // 此时的 getSalary() 已经计算过了生日的钱和提成的前 , 因此在这里只需要计算加上本类的独特属性底薪就可以了 . // 这就是继承的好处 .
       }
}
总结: 这个题目要作出来很简单,要是做的符合面相对象的原则,就不那么简单了,首先,要把符合要求把所有类都作成完全私有的,这样子类就不能随便使用父类中的属性,虽然现在子类中有父类中的属性.如果要在子类在从新申请父类中有的属性,这样就浪费了空间,这样就会想到调用父类中能够操作父类属性的方法.很自然的就会想到父类中的构造方法.这样就用新的值初始化了父类中的属性,和子类中的属性,这样不会造成内存的浪费,而且会使代码简单易懂.也就是把共性放在父类中,把个性放在子类里边简单.
 
Java中的设计通常会采用继承和多态的概念来处理这种场景。我们可以创建一个`Employee`抽象,然后为具体的员工型如`SalaryEmployee`, `HourlyEmployee`等定义子,它们分别继承`Employee`并实现`getSalary()`或`getHoursAndRate()`等计算工资的方法。 例如: ```java abstract class Employee { protected String name; public Employee(String name) { this.name = name; } // 抽象方法,需要在子中具体实现 abstract int getPayment(); // 其他通用的方法... } class SalaryEmployee extends Employee { private double salary; public SalaryEmployee(String name, double salary) { super(name); this.salary = salary; } @Override public int getPayment() { return (int)salary; // 转换为整数支付 } } class HourlyEmployee extends Employee { private double hourlyRate; private int hoursWorked; public HourlyEmployee(String name, double hourlyRate, int hoursWorked) { super(name); this.hourlyRate = hourlyRate; this.hoursWorked = hoursWorked; } @Override public int getPayment() { return (int)(hourlyRate * hoursWorked); // 按小时计算工资 } } ``` 在这个例子中,你可以创建一个`Employee`型的列表,然后通过`getPayment()`方法统一处理不同型的员工工资,实现了多态性。比如: ```java List<Employee> employees = new ArrayList<>(); employees.add(new SalaryEmployee("张三", 5000)); employees.add(new HourlyEmployee("李四", 20, 40)); for (Employee employee : employees) { System.out.println(employee.getName() + " 的工资是:" + employee.getPayment()); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炼丹狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值