用类图描述设计
设计过程
抽象的原则
1.封装
①【属性的封装】
1.将类的属性进行私有化处理,不允许外部程序进行直接访问,并对外提供统一的方法用于设置和读取私有属性。
2.实现访问控制,限制属性访问(但不是拒绝属性访问)。
作用:只能通过规定的方法访问数据,方便在方法中加入控制语句,防止不合法语句赋值。
private String name; private int age; private String sex ; public Demo01_Package(){} public Demo01_Package(String name, int age) { super(); this.name = name; setAge(age); } public void setAge(int age){ if(age>0&&age<120){ this.age=age; }else{ System.out.println("age输入不合法"); this.age=-1; } } public int getAge(){ return this.age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; }
Test:
Demo01_Package oop=new Demo01_Package(); oop.setAge(1000); System.out.println(oop.getAge()); Demo01_Package oop1=new Demo01_Package("zhangsan",10000); System.out.println(oop1.getAge()); System.out.println(oop);
②【封装】
除了属性的封装之外,将需要重复使用的代码提取到方法之中,这叫方法的封装;
将相同的属性和方法抽象成一个类,这也是封装的思想;
2.继承
【继承】
①子类继承父类,使用extends关键字。
②子类中需要访问父类成员。使用super关键字。
super.属性 访问父类属性。
super.方法() 访问父类方法。
如果,子类中没有同名的属性和方法覆盖掉父类,则依然可以直接使用this.属性调用从父类中集成的非私有属性。
但是,如果子类中重写了与父类同名的属性,this.属性访问的是本类,super.属性访问的是父类属性。
在子类构造函数中,直接使用super();表示调用父类构造,而且,super()函数必须在子类构造的第一行。
public Demo03_SoftEngineer() { super(); } public Demo03_SoftEngineer(String type) { super(); this.type = type; } public Demo03_SoftEngineer(String no, String name, String entertime, String type) { super(no, name, entertime); System.out.println(this.name+"****");//访问本类中的属性 System.out.println(super.name+"****");//父类,和父类属性不同 System.out.println(name+"****");//()里String定义的属性和syso的不一样,和局部变量不同 this.type = type; }
注意:即使使用super关键字也不能访问父类的私有属性和私有方法。不同的包中如果是默认的不可以访问,protected可以。
③子类可以访问父类哪些属性和方法?
④继承后的初始化顺序(了解)
父类属性-->父类构造-->子类属性-->子类构造
⑤在java中,继承只能单继承。
不能多继承,但可以多层继承。超类,基类,都是父类。
public class Test1{}
public class Test2 extends Test1{}
public class Test3 extends Test2{}
此时,Test3就可以得到Test2和Test1两个类中的非私有属性。
方法重写:
在子类中重写父类方法。
要求:
方法名相同,参数列表相同,返回值相同,访问控制符不能比父类更严格。
方法重载:
在同一个类中方法名相同参数列表名不同,与返回值与访问修饰符无关的多个方法,构成方法重载。
参数列表:
参数的个数,数据类型,多个参数的前后顺序不同,都属于参数列表不同。
方法重载的典型应用:
构造函数重载。
public void say(){ System.out.println("我说了一句话"); } private int say(String str){// System.out.println("我说了一句话"+str); return 1; }
3.多态
【多态】
1.同一种事物,由于条件的不同,展示出不同的结果,叫做多态。
@param i
2.程序中的多态:同一个引用类型由于使用不同的对象实例而执行不同的操作。
实例:
中国人说中国话,英国人说英国话。
Chinese c=new Chinese(); c.say();不是多态
English e=new English(); e.say();
人们有的说中国话,有的说英国话。
Person p=new Chinese(); p.say();多态
Person p=new English(); p.say();
3.实现多态的条件:
(1)子类继承父类
Instrument i=new InstrumentPiano();
(2)子类重写父类方法
(3)父类引用指向子类对象//保证:同一个父类引用类型,使用不同的子类对象实例,而执行不同的操作
Person p=new Person(); Chinese c=(Chinese)p; //ClassCastException转换异常,因为p 不是chinese的实例,强转会造成类转换异常。
Person p=new English(); Chinese c=(Chinese)p; //ClassCastException转换异常,因为p 不是chinese的实例,强转会造成类转换异常。
Person p=new Chinese(); Chinese c=(Chinese) p; //对,p是chinese的实例。
Test03_Moto bus=new Test03_Moto(); Test03_Bus b=(Test03_Bus)bus; b.say();
if(bus intanceof Test03_Bus){ Test03_Moto bus=new Test03_Moto(); Test03_Bus b=(Test03_Bus)bus; b.say(); system.out.println("yes"); }else{ system.out.println("no"); }//结果是yes
内部类、外部类:
class Person{ private String name; public void say(){ System.out.println("Person类的say方法"); }
1.内部类:声明在类内部的一个类,叫做内部类。
2.内部类的特点:内部类可以使用public,省略,protected,private等各种访问修饰符修饰。外部类只能是public和省略。
3.内部类编译以后是独立的.class文件,文件名是“外部类名$内部类名.class”
因此,自定义类名时,不使用$。
4.内部类中可以访问外部类的属性和方法(包括私有的),如果没有重名,可以直接访问,如果与内部类已有属性重名,
可以使用外部类名.this.属性名访问。
5.外部类中不能访问内部类中的属性,public也不行。
如果需要访问,可以先拿到内部类的对象,使用对象访问内部类属性(通过这种属性,包含类可以访问内部类的私有属性)。
Test t=new Test(); System.out.println(t.age);