======================================================================
java第四天
======================================================================
高内聚(independence): 一个对象独立[注意独立,不要其他对象的帮助]完成一个工作.
======================================================================
(1)封装(encapsulation): 该隐藏的隐藏,该公开的公开.属性(property)[隐藏],方法[公开(有些公开,有些隐藏.)].//给自己用的方法私有,给别人用的方法公开. //公开声明,隐藏实现.[只修改实现这样对架构的影响最小.] 封装和弱藕合有关系
======================================================================
(2)继承(inheritance):共性写在父类,个性(individual)写在子类. //单继承是java简单性的表现. java中的,父类的私有属性不继承到子类中.子类中.创建子对象要先创建一个父类,然后在加上一个子类对象[子类对象=父类对象+子类对象独特的地方].子类里边有父类和子类.子类能不能访问
单继承的好处: 类和类成为树状关系,不是网状结构.[java简单性的体现,但是能通过接口来实现多继承]。
private: 不能继承.(但是子类里边有这个属性,如果修饰方法,子类就不能用了,属性的话,还能用一下.)
default: 同包子类能继承,不同包子类不能继承.
protected: 同包或者不同包的子类.
public: 任何类型:
protected: 的特殊使用方法如下:
package b;
package b;
import a.*;
class TestProteced {
publicstaticvoid main(String[] args) {
B b = new B();
b.m(); // 只有在子类的内部才能用父类的protected属性和方法.在即使是子类的对象外部使用也不行.
}
}
class B extends A {
class B extends A {
void mm() {
m(); // 在子类内部可以使用父类中protected 属性和方法.
}
}
package a;
package a;
class A{
void m(); // 外包中的方法.
}
(3)多态(polymorphism):方法覆盖: override //父子类才发生覆盖.方法名相同,参数表相同,返回值也要相同.修饰符可以不同[权限要越来越大[严->宽]] //1.4 中以上对
多态: 一个行为在不同的环境下有不同的行为方式.
多态分为:编译时多态[方法重载],和运行时多态.
//5.0: 不强制返回值一样(两个类必需)也可以返回类型的子类;
(3)多态(polymorphism):方法覆盖: override //父子类才发生覆盖.方法名相同,参数表相同,返回值也要相同.修饰符可以不同[权限要越来越大[严->宽]] //1.4 中以上对
多态: 一个行为在不同的环境下有不同的行为方式.
多态分为:编译时多态[方法重载],和运行时多态.
//5.0: 不强制返回值一样(两个类必需)也可以返回类型的子类;
class Animanl{
inta=10;
protected A eat(){ // B 是 A 的子类.
System.out.println("hehe");
returnnull;
}
}
class Dog extends Animanl{
int a=10; // 属性的遮盖.(shadow)
super.a=1; // 要访问父类中的属性或者方法.用super 关键字.
super.eat(); // 调用父类的方法.
protected B eat(){ // 在jdk 5.0 中返回值可以不同,有条件就是返回值可以是覆盖对象返回值的子类.
System.out.println();
returnnull;
}
}
(3) 构造一个对象的过程:
一个对象的构造过程:
一个对象的构造过程:
1.分配空间,
2.初始化属性
3.调用构造方法.
(4) 有父类的构造过程:有父类的类:
2.初始化属性
3.调用构造方法.
(4) 有父类的构造过程:有父类的类:
1. 递归的构造父类对象.//父类可能还有父类.
2. 分配本类的空间.
3. 初始化本类的属性.
4. 调用本类的构造方法.
//如果不想记那么多构造方法的语法,那么最好在每个类加上无参的构造方法.
有父类的类的构造方法例子:
---------------------------------------------
package test;
2. 分配本类的空间.
3. 初始化本类的属性.
4. 调用本类的构造方法.
//如果不想记那么多构造方法的语法,那么最好在每个类加上无参的构造方法.
有父类的类的构造方法例子:
---------------------------------------------
package test;
class Test{
publicstaticvoid 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{
class A{
/*
public A(){
super();
}
*/ 默认的产生[父类的无参构造方法].
}
===============================
package test;
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;
======================================================================
(5) 多态(polymorphism):Animal a= new Dog();
编译时类型(引用类型) 运行时类型
主观(把它看成什么) 客观
3条原则:
<1> 对象运行时类型不变.
<2> 只能对一个引用调用其编译时类型定义的方法. //对象只能调用父类中定义的方法.
<3> 运行的时候,会根据运行时类型找,覆盖之后的方法. //
例子:
VCD,DVD机的例子:
遥控器()
package test;
publicclass TestPoly {
publicstaticvoid 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;
(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;
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;
publicclass TestEmployee {
publicstaticvoid 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;
privateintbirthday;
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() {
returnname;
}
}
// 雇员类的子类,
class SalariedEmployee extends Employee {
privateintmonthsalary; // 自己私有的属性,每个月的基本工资.
SalariedEmployee() {
} // 无参构造函数,记住最好写上.
// 有参构造函数;
SalariedEmployee(String name, int birthday, int monthsalary) {
super(name, birthday); // 用来初始化,父类的的公有的属性.
this.monthsalary = monthsalary;// 初始化子类的属性.
}
// 覆盖了父类的获得工资的方法.因为每类员工都有不同的工资方法.
double getSalary(int month) {
returnsuper.getSalary(month) + monthsalary; // 生日的钱+基本工资;
}
}
// 雇员类的子类,小时工.
class HourlyEmployee extends Employee {
// 自己私有的属性.每小时的工钱,和工作的小时数.
privateinthoursalary;
privateinthour;
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) {
returnsuper.getSalary(month) + hoursalary * 160 + 1.5 * hoursalary
* (hour - 160); // 生日的钱+小时*每小时的工资;
} else
returnsuper.getSalary(month) + hoursalary * hour; // 生日的钱+小时*每小时的工资;
}
}
// 雇员类的子类:
class SalesEmployee extends Employee {
// 自己私有的属性: 销售额,提成率;
privateintsale;
privatedoublerate;
SalesEmployee() {
}
// 有参构造函数,初始化类.
SalesEmployee(String name, int birthday, int sale, double rate) {
super(name, birthday); // 公有属性;
this.sale = sale; // 私有属性;
this.rate = rate;
}
// 覆盖了父类的获得工资的方法.
double getSalary(int month) {
returnsuper.getSalary(month) + sale * rate; // 生日的钱+提成;
}
}
// SalesEmployee的子类,继承了SalesEmployee 的所有属性.
class BasePlusSalesEmployee extends SalesEmployee {
// 本类私有的属性: 底薪. 其他全部继承子父类.
privateintbasesalary;
BasePlusSalesEmployee() {
}
BasePlusSalesEmployee(String name, int birthday, int sale, double rate,
int basesalary) {
super(name, birthday, sale, rate); //初始化,和父类相同的属性
this.basesalary = basesalary; //初始化自己的属性;
}
//覆盖了父类的获得薪水的方法.
double getSalary(int month) {
returnsuper.getSalary(month) + basesalary; //此时的getSalary() 已经计算过了生日的钱和提成的前,因此在这里只需要计算加上本类的独特属性底薪就可以了. //这就是继承的好处.
}
}
总结: 这个题目要作出来很简单,要是做的符合面相对象的原则,就不那么简单了,首先,要把符合要求把所有类都作成完全私有的,这样子类就不能随便使用父类中的属性,虽然现在子类中有父类中的属性.如果要在子类在从新申请父类中有的属性,这样就浪费了空间,这样就会想到调用父类中能够操作父类属性的方法.很自然的就会想到父类中的构造方法.这样就用新的值初始化了父类中的属性,和子类中的属性,这样不会造成内存的浪费,而且会使代码简单易懂.也就是把共性放在父类中,把个性放在子类里边简单.
本文详细介绍了Java面向对象的四大特性:封装、继承、多态及构造过程。通过具体实例讲解了如何利用这些特性进行类的设计,并展示了如何通过多态实现不同子类间的差异屏蔽。
180

被折叠的 条评论
为什么被折叠?



