封装和继承
封装性:
-
(根据对属性的封装说明)把对成员变量的访问私有化,通过一个公共的方法间接的实现
-
好处:提高了代码的安全性,可读性,复用性
-
因为对所有的属性都要进行赋值和取值,系统制定了一套默认规则—set,get方法
-
set–完成赋值
- 构成:修饰词 返回值 方法名(参数列表){方法体
返回值
}- 返回值:不需要返回值—这里写void
- 方法名:set + 对应成员变量的名字,成员变量的首字母大写
- 参数列表:只有一个参数,参数的类型与成员变量的类型一致,名字就是成员变量的名字
- 方法体:不需要返回值,我们可以写this.成员变量 = 形参的名字
- 构成:修饰词 返回值 方法名(参数列表){方法体
-
get–完成取值
- 构成:修饰词 返回值 方法名(参数列表){方法体
返回值
}- 修饰词:一般是public
- 返回值:类型与成员变量一致
- 方法名:get + 对应成员变量的名字,成员变量的首字母大写
- 参数列表,不需要参数
- 方法体:return 成员变量
- 构成:修饰词 返回值 方法名(参数列表){方法体
-
快捷键:shift + alt + s
脏数据:在程序中出现的不符合逻辑的数据
- 原因:直接将数据交给了成员变量
- 如何避免脏数据?
- 不要将值赋给成员变量—让成员变量不可见,将成员变量私有化
- 通过方法间接的访问他—先过滤后赋值.
public class Demo2 {
public static void main(String[] args) {
//开枪射击
Gun gun = new Gun();
Scanner
//gun.bulletNumber = -5;
// gun.addBulletNumber(-5);
// gun.shoot();
gun.setBulletNumber(-5);
}
}
class Gun{
//private属于修饰词,被他修饰的成员只在当前类中可见
private int bulletNumber;
private int age;
private int height;
private int model;
private String name;
//添加子弹的方法
//相当于过滤
// public void addBulletNumber(int number) {
// if(number < 0) {
// this.bulletNumber = 0;
//
// }else {
// this.bulletNumber = number;
// }
// }
public int getBulletNumber() {
return bulletNumber;
}
public void setBulletNumber(int bulletNumber) {
this.bulletNumber = bulletNumber;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getModel() {
return model;
}
public void setModel(int model) {
this.model = model;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//开枪射击
public void shoot() {
if(bulletNumber > 0) {
--bulletNumber;
}
System.out.println("剩余的子弹数量: " + bulletNumber);
}
}
继承
重写:
-
定义:当子类有与父类方法同名(方法的所有位置都想同)的时候,我们称为重写.
-
注意点:子类的同名方法相当于给父类的方法覆盖了,父类的方法不会再被调用
-
作用:在不改变父类方法名的前提下,实现父类现有功能的基础之上,实现一些额外的功能,实现了一些对原有方法的扩充.
-
this:是一种引用数据类型,代表当前的对象,保存的是当前对象过的地址
-
super:不是引用数据类型,可以代表父类,通过super可以调用父类的方法
-
注意点总结:
- 私有方法不能被重写
- 同名方法子类的权限大于等于父类的
- 静态的方法只能覆盖静态的.
调用方法的原理:
-
子类调用父类的方法,首先由引用找到当前的子类对象,在当前的对这个方法,找到了直接调用,找不到就到直接的父类中找,找到了调用,找不到上找,一直找到object类,还没找到,证明确实没有这个方法
-
子类方法的优先级高于父类的
public class Demo3 {
public static void main(String[] args) {
Iphone iphone = new Iphone();
iphone.color = "red";//调用的父类的属性
iphone.callPhone();//调用的父类的方法
iphone.fangshui();//调用自己的特有的方法
}
}
//创建他们的父类
//如果一个类没有写父类,那他的父类默认就是object
class Phone{
String color;
int model;
public void fangshui() {
System.out.println("防水");
}
public void callPhone() {
System.out.println("打电话");
}
}
//创建IPhone和HUAWEI类
// 子类 extends 父类
class Iphone extends Phone{
// String color;
// int model;
String gui;
//重写父类方法
public void callPhone() {
//System.out.println("打电话");
//this.callPhone();//这里会优先找子类的同名方法,造成死循环.
super.callPhone();//直接调到的是父类的方法
//写自己的功能
System.out.println("写自己的功能");
}
// public void fangshui() {
// System.out.println("防水");
// }
}
class Huawei extends Phone{
// String color;
// int model;
public void niu() {
System.out.println("niubi");
}
}
继承中使用构造方法
-
当一个类只有一个带参数的构造方法,只能使用带参数的,不能使用无参的,如果想使用,必须手动建立无参的构造方法
-
创建构造方法的时候,如果我们不手动调用super,系统会自动调用父类无参的构造方法
原因:因为父类中也有成员变量需要进行初始化,而对象的成员变量必须由自己的构造方法进行初始化,所以必须调用super,每个构造方法都有默认的super
-
当父类中只有带参数的构造方法,子类的构造方法中就必须在第一行手动调用父类的带参数的构造方法super(参数)
原因:因为在子类中有可能用到父类的成员变量,而成员变量在使用前必须进行初始化,否则不能使用总结:在继承体系中,最好就是将父类的无参、有参构造方法都生成.
public class Demo4 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.play();
}
}
class Anima{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Anima() {
super();
}
public Anima(String name) {
//System.out.println("hahah);//super必须放在第一行
super();
this.name = name;
}
}
class Dog extends Anima{
public Dog(){
//super();//默认的代码,代表在调用父类空参的构造方法
super("bingbign");
}
public Dog(String name){
super(name);//代表调用父类有参的构造方法
this.setName(name);
}
public void play() {
System.out.println("play");
}
}