目录
封装:
为什么需要使用封装?
当我们在给属性赋值的时候,可能会赋不符合实际情况的值,我们可以使用封装来对用户输入的值进行限制。
使用的步骤:
1.给属性加修饰符 private
2.编写setter [设置值] /getter [获取值]
3.在setter方法中写判断语句
如:
public class Student {
//私有化属性
private int age;
//编写setter 方法给age赋值
public void setAge(int age){
//判断语句 如果age大于100或者小于0,则输出语句并将50赋值给当前的age,否则将我们设置的值赋给age
if(age>100 || age<0){
System.out.println("年龄输入错误,默认50");
this.age=50;
return;
}
this.age=age;
}
//使用gettet方法 接收值
public int getAge(){
return age;
}
public void show(){
System.out.println("年龄是:"+age);
}
}
public class TestStudent {
public static void main(String[] args) {
Student s= new Student();
s.setAge(10);
int age = s.getAge();
System.out.println(age);
}
}
继承:
当有多个类中有多个一样的属性或者方法的时候,我们考虑优化——继承。
什么叫继承:一个类不需要自己写某个属性或者方法,然后就有了其他的一个类的属性或者方法
java中的继承也是需要满足某种关系——is a
如: dog is a Animal
如何表示:
关键字 extends 如:Dog extends Animal
要求:
一个类同时只能继承一个父类。
Object类是所有类的父类
如下面的例子:
//定义一个Pet父类
public class Pet {
//private 封装
private String name; //名字
private int health; //健康值
private int love; //亲密度
}
//定义一个Dog子类
//extends表示继承 也就是说Dog子类也有Pet父类中的name,health,love
public class Dog extends Pet{
private String strain; //品种
}
//定义一个Penguin子类
public class Penguin extends Pet {
private String sex; //性别
}
构造方法的执行顺序:
当我们创建对象的时候 ,是先到子类的对应的构造方法,如果子类中没有显示的调用父类的构造方法,则表示默认调用父类的无参构造方法,如果显示的调用了父类的构造方法,则会根据我们的需求去调用对应的构造方法。
访问修饰符
public (公共的) 处处可访问
private (私有的)只能在本类可访问
defautl (缺省的)本包以及其子类
protected 本包以及其他包中子类
重写:
就是父类中的方法不能灵活的满足子类的需求了
方法名相同,参数列表相同,返回值类型相同或者是其子类,访问修饰符范围不能严于父类【简单记忆:全都和父类一样】
如果子类重写了父类的方法,则执行的就是子类重写之后的方法。
重载:
在一个类中,方法名相同参数列表不同【顺序 个数 类型】和其他无关
多态:
一种事务在不同的条件下所呈现的状态不同。
为什么需要:根据oop相关的设计原则(开闭原则、单一原则、本末倒置原则)来提高程序运行效率
语法:父类 父类的引用=new 子类()
编译看左边 运行看右边。当子类重写的父类的方法之后,调用该方法的时候执行的是子类的方法
调用子类特有的方法:向下转型 instanceof
例子:
//Dog类
public class Dog extends Pet{
private String strain; // 品种
public Dog() { // 构造无参方法
}
public Dog(String strain) { // 构造有参方法
this.strain = strain;
}
public String getStrain() { // getter方法
return strain;
}
public void setStrain(String strain) { // setter方法
this.strain = strain;
}
/*狗狗生病了 需要去医院*/
public void goHospital(){
System.out.println("狗狗生病打针吃药...");
setHealth(getHealth()+5);
}
}
//Penguin类
public class Penguin extends Pet{
private String sex; // 性别
public Penguin() { // 构造无参方法
}
public Penguin(String sex) { // 构造有参方法
this.sex = sex;
}
public String getSex() { // getter方法
return sex;
}
public void setSex(String sex) { // setter方法
this.sex = sex;
}
public void goHospital(){
System.out.println("企鹅生病睡觉疗养.....");
setHealth(getHealth()+3);
}
}
//Pet类
public abstract class Pet {
private String name;
private int health;
private int love;
//构造无参有参方法
public Pet() {
}
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
//getter setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
/*在父类中创建了带宠物看病的方法,但是每个宠物看病治疗的方式不同,
* 所以不能在Pet中 的 goHospital ()方法中写具体的看病方式
* 所以将该方法变成抽象方法 该方法所在的类变成抽象类
*/
public abstract void goHospital() ;
}
//Master类
public class Master {
/*
* 主人带狗狗 去医院 或者带企鹅去医院 方法的大部分内容是一样的 只有参数不同,
* 没有做到程序的可复用性。
* 参数都有一个特点:都是 Pet 的子类,那么我么可以将父类作为参数;
* 引出的问题:父类【pet】中没有 goHospital(),自然去Pet类中不上goHospital()方法
*
* */
public void hospital(Pet pet){
if (pet.getHealth()<80){
pet.goHospital();
}else{
System.out.println("宠物很健康....");
}
}
}
public class TestMaster {
public static void main(String[] args) {
Master m = new Master();
/*Pet已经是抽象类不能创建对象了,如何指明是具体的哪个宠物生病呢?
* 多态语法
* 父类 父类的引用 = new 子类();
* 编译看左边,运行看右边
* */
Pet pet = new Penguin();
pet.setHealth(70);
m.hospital(pet);
System.out.println(pet.getHealth());
}
}