三大特性:
封装、继承、多态
1.封装
隐藏事物的内部细节,提供对外访问的方法.作用:保证数据安全性;简化代码实现复用.
- 对功能的封装:将功能声明为一个方法.作用:简化代码,实现代码复用.
- 对属性的封装:将属性私有化,给它提供公有的获得属性get方法和设置属性set方法.
- 作用:保护数据的安全性.
- 自动生成get和set方法:选中类的空白地方->鼠标右键Source->Generate getters and setters->勾选你要生成get和set方法的属性->点击Generate按纽.
eg:/**
* 年龄属性
*/
private int stuAge;
/**
* 获得属性值的方法
* @return
*/
public int getStuAge() {
return stuAge;
}
/**
* 设置属性值的方法
* @param stuAge
*/
public void setStuAge(int stuAge) {
if (stuAge>0) {
this.stuAge = stuAge;
}else {
System.out.println("你的年龄输入有误!");
}
}
2.继承
满足is-a关系;
-
继承的作用:减化代码,实现代码复用.
-
被继承类:父类,基类,超类
继承的类:子类,衍生类,派生类. -
继承的关键字:extends
-
子类可以继承父类公有的或受保护的属性和方法,不能继承继承父类私有的属性和方法;子类不能继承父类构造方法.
-
构造方法执行:每次创建一个子类对象时,我们自己不调用父类构造,系统会默认先调用父类无参构造,再调用子类指定构造;如果我们调用父类指定构造,系统不会调用父 类无参构造,而按照我们指定父类构造来调用,再调用子类指定构造.
-
继承的特点:
单根性:一个Java类只能直接继承一个父类.
传递性:A类继承B类,B类继承C类,A类就间接继承C类.
eg:/**
* 动物类
*/
public class Animal {
/**
* 毛的颜色
*/
public String color;
}
/**
* 宠物类
*/
public class Pet extends Animal{
/**
* 昵称的属性
*/
public String nickName;
/**
* 品种的属性
*/
public String brand;
/**
* 健康值的属性
*/
public int health;
/**
* 性别的属性
*/
protected char sex;
public Pet() {
System.out.println("这是宠物类无参构造");
}
public Pet(String nickName,String brand,int health,char sex) {
System.out.println("这是宠物类全参构造");
this.nickName=nickName;
this.brand=brand;
this.health=health;
this.sex=sex;
}
/**
* 吃的方法
*/
protected void eat() {
System.out.println("宠物在吃东西");
}
}
/**
* 猫类,,继承宠物类
*/
public class Cat extends Pet{
public Cat() {
System.out.println("这是猫类无参构造");
}
public Cat(String nickName,String brand,int health,char sex) {
//super();//调用父类无参构造
super(nickName, brand, health, sex);
System.out.println("这是猫类全参构造");
// this.nickName=nickName;
// this.brand=brand;
// this.health=health;
// this.sex=sex;
}
}
3.访问修饰符
4.方法重写:
注: 兼容两种类型一致或是父子关系.
4.1:适用场景
当从父类继承过来的方法无法满足子类的需求时,就需要方法重写.
4.2:方法重写的条件:
- 发生在有继承关系子类中.
- 重写的方法与父类被重写的方法方法名和参数列表要一致.
- 重写的方法返回值类型与被重写的方法返回值类型相同或兼容.
- 重写的方法访问修饰符与被重写的方法访问修饰符相同或更大.
4.3:方法上面用@Override可以检查当前的方法是否是重写的方法.无特殊情况重写方法上面 加@Override注解.
eg:/**
* 宠物类
*/
public class Pet{
/**
* 昵称的属性
*/
public String nickName;
/**
* 品种的属性
*/
public String brand;
/**
* 吃的方法
*/
public void eat() {
System.out.println("宠物在吃东西");
}
}
/**
* 猫类,,继承宠物类
*/
public class Cat extends Pet{
/**
* 重写父类吃的方法
*/
@Override
public void eat() {
System.out.println("猫在吃鱼");
}
}
/**
* 狗类,继承宠物类
*/
public class Dog extends Pet{
/**
* 重写父类吃的方法
*/
@Override
public void eat() {
System.out.println("狗在吃骨头");
}
}
5.方法重写 VS 方法重载
5.1:作用不同
- 当子类继承父类的方法后无法满足子类的需求时,才用方法重写;
- 方法重载解决同一个类中功能相同的方法的命名和调用问题.
5.2:条件不同:
- 方法重写的条件:发生在有继承关系子类中;
1.重写的方法与父类被重写的方法方法名和参数列表要一致;
2.重写的方法返回值类型与被重写的方法返回值类型相同或兼容.
3.重写的方法访问修饰符与被重写的方法访问修饰符相同或更大. - 方法重载的条件:在同一个类中;
方法名相同;
参数列表不同.
5.3:检查不同
方法重写可以用@Override检查;方法重载只能自己人为检查.
6.super:指代父类对象的引用.
- 调用父类属性:super.属性名.
- 调用父类的方法:super.方法名(实参列表);
- 调用父类的构造方法:super(实参列表),只能写在构造方法的第一句;//常用
7.this vs super
7.1:作用不同
this指代当前对象;super指代父类对象.
7.2:调用不同
this可以调用当前类的属性,方法和构造方法,且调用构造方法时只能写在构造方法的第一句;super可以调用父类的属性,方法和构造方法,且调用构造方法时只能写在构造方法的第一句;
7.3:能否省略
当一个方法的形参名称与属性名相同时,为了以示区别,this是不可以省略;super没有一定要用的地方.
8.多态
多态是建立在继承和重写的基础上.
- 1:生活中多态的概念:同一种事物由于外界条件不同,而执行不同操作或产生不同状态.
- 2:程序中多态的概念:用父类或父接口作为数据类型,指向不同子类对象调用同一个方法,而执行不同操作.
- 3:多态的第一种应用:用父类或父接口作为数据类型,创建不同子类对象,而执行不同操作.
eg://调用构造方法创建对象,多态的第一种应用,用父类作为数据类型,创建子类对象
Pet p1=new Cat();
//用对象调用方法
p1.eat();
- 4:多态的第二种应用:用父类或父接口作为方法形参,实参传递子类对象,而执行不同操作.
eg:/**
* 人类
*/
public class Master {
/**
* 多态的第二种应用:用父类作为方法形参,实参传递一个子类对象
* @param p
*/
public void feedPet(Pet p) {
System.out.println("主人在喂食");
p.eat();
}
}
//调用构造方法创建对象
Cat c1=new Cat();
Dog d1=new Dog();
Master m1=new Master();
//用对象调用方法,多态的第二种应用,用父类作为方法形参,实参传递的是子类对象
m1.feedPet(c1);
m1.feedPet(d1);
- 5:多态的第三种应用:用父类或父接口作为方法的返回值类型,实际返回一个子类对象.
eg:/**
* 多态的第三种应用:用父类作为方法的返回值类型,实际返回的是子类对象
* @param name
* @return Pet
*/
public Pet lookPet(String name) {
//声明一个变量存宠物对象
Pet p1=null;
if (name.equals("猫")) {
p1=new Cat();
}else if (name.equals("狗")) {
p1=new Dog();
}
return p1;
}
//调用构造方法创建对象,多态的第三种应用,用父类作为方法返回值类型,实际返回子类对象
Master m2=new Master();
//用对象调用方法
Pet p1= m2.lookPet("猫");
Pet p2= m2.lookPet("狗");
p1.voice();
p2.voice();
- 6:多态的作用:增强程序可维护性;增加程序的可扩展性.
9.引用数据类型转换:
9.1:向上转型
将对象存在父类或父接口类型中,向上转型是自动转换.
注意: 向上转型的对象只能调出从父类继承的属性和方法或重写父类的方法,不能调出子类独有属性和方法
- 语法: 父类型 变量名=子对象
eg://调用构造方法创建对象
Pet p1=new Cat();
//用对象调用方法
p1.eat();
9.2:向下转型
将父类型的对象转换为原本子类对象,向下转型是强制类型转换.
注意: 向下转型的对象可以调出自己独有方法和属性,也可以调用从父类继承的方法或属性.
- 语法:子类类型 变量名=(子类类型)父类型对象;
eg://向下转型:将父类型的p1转换为原本Cat类,
Cat d1=(Cat) p1;
d1.playBall();//可以调出自己独有方法或属性
9.3:转型异常
向下转型有风险,如果父类型的对象转换为子类型时不对应,会报ClassCastException异常.为了减少向下转型的风险,对父类型的对象进行判断,判断完再转换.
- 语法:判断当前这个父类型的对象原来的类型是否是某个子类型
boolean result=父类型的对象 instanceof 子类型
eg:if (p1 instanceof Cat) {
Cat d1=(Cat) p1;
d1.playBall();//可以调出自己独有方法或属性
}else if(p1 instanceof Dog) {
Dog d2=(Dog) p1;
d2.swimming();
}
个人笔记,思路,仅供参考