在对象的外部,为对象的属性赋值,可能存在非法数据的录入。
就目前的技术而言,并没有办法对属性的赋值加以控制。
例如:
stu.age=10000;封装
封装概念:尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限。
访问修饰符:private(可将属性修饰为私有,仅本类可见)
私有属性在类的外部不可访问
class Student{
String name;
private int age;
String sex;
}
public class Test{
public static void main(String[] args){
Student stu=new Student();
stu.age=10000;// 编译出错,私有属性在类的外部不可访问
}
}
提供公共访问方法,以保证数据的正常录入
以访问方法的形式,进而完成赋值与取值操作
赋值:setXXX() 使用方法参数实现赋值
取值:getXXX() 使用方法返回值实现取值
class Student{
String name;
private int age;
String sex;
public void setAge(int age){
this.age=age;
}
public void getAge(){
return this.age;
}
}
在公共方法的内部,添加逻辑判断,进而过滤掉非法数据,以保证数据安全。
class Student{
String name;
private int age;
String sex;
public void setAge(int age){
if(age>0&&age<=150){//指定有效范围
this.age=age;
}else{
this.age=20;//录入非法数据时的默认值
}
}
public void getAge(){
return this.age;
}
}
私有属性,类外部不能使用,通过getset方法访问
get/set方法是外界访问对象私有属性的唯一通道,方法内部可对数据进行检测和过滤
程序中的继承,是类与类之间特征和行为的一种赠与或获得。
两个类之间的继承关系,必须满足 “is a”的关系。例如:
Animal:父类 Dog、Cat:子类
Dog is an Animal
Cat is an Animal
可根据程序需要使用到多个具体的类,进行共性抽取,进而定义父类
功能越精细,重合点越多,越接近父类。
功能越粗略,重合点越少,越接近Object类。(万物皆对象概念)
语法:class 子类 extends 父类{ } //定义子类时,显示继承父类
应用:产生继承关系之后,子类可以使用父类中的属性和方法,也可定义子类独有的属性和方法。
好处:既可提高代码的复用性,又提高代码的可扩展性。
特点:java为单继承,一个类只能有一个直接父类,但可以多级继承,属性和方法逐级叠加。
- 构造方法:类的构造方法,只负责创建本类对象,不可继承。
- private修饰的属性和方法:访问呢修饰符的一种,仅本类可见。
- 父子类不在同一个package中时,default修饰的属性和方法:访问修饰符的一种,仅同包可见。
| 本类 | 同包 | 非同包子类 | 其他 | |
|---|---|---|---|---|
| private | √ | × | × | × |
| default | √ | √ | × | × |
| protected | √ | √ | √ | × |
| public | √ | √ | √ | √ |
不写修饰符默认为default
方法的覆盖当父类提供的方法无法满足子类需求时,可在子类中定义和父类相同的方法进行覆盖(Override)
方法覆盖原则:
- 方法名称、参数列表、返回值类型必须与父类相同。
- 访问修饰符不能比父类更严格。
方法覆盖的执行:子类覆盖父类方法后,调用时优先执行子类覆盖后的方法。
在子类中,可直接访问从父类继承到的属性和方法,但如果父子类的属性或方法存在重名(属性遮蔽、方法覆盖)时,需要加以区分,才可专项访问。
super关键字可在子类中访问父类的方法。
使用“super.”的形式访问父类的方法,进而完成在子类中的复用;再叠加额外的功能代码,组成新的功能。
使用“super.属性名”访问父类属性
代码示例:
class A{
int value=10;
public void method(){
System.out.println("父类方法体...");
}
}
class B extends A{
int value=20;
public void method(){
super.method();//父类方法体
//可添加子类额外功能代码,例如:
System.out.println("子类额外代码...");
}
public void print(){
int value=30;
System.out.println(value);//实例变量
System.out.println(this.value);//本类实例变量
System.out.println(super.value);//父类实例变量
}
}
public class Test{
public static void main(String[] args){
B b=new B();
b.method();
b.print();
}
}
this:当前对象的引用
super:父类对象的引用
在具有继承关系的对象创建中,构建子类对象会先构建父类对象。
由父类的共性内容,叠加子类的独有内容,组合成完整的子类对象。
构建过程中,先执行父类的构造方法,再执行子类的构造方法。
super():表示调用父类无参构造方法。如果没有显示书写,隐式存在于子类构造方法的首行。
super(实参):表示调用父类有参构造方法。
this表示当前对象引用,调用本类(包括继承)的属性、方法、本类构造方法。
super表示父类对象引用,调用父类的属性、方法、构造方法。
this或super使用在构造方法中时,都要求在首行。当子类构造中使用了this()或this(实参),即不可再同时书写super()或super(实参),会由this()指向的构造方法完成super()的调用。
class A{
public A(){
System.out.println("A-无参构造");
}
public A(int value){
System.out.println("A-有参构造");
}
}
class B extends A{
public B(){
super();//调用父类无参构造
System.out.println("B-无参构造");
}
public B(int value){
this();//调用本类无参构造
System.out.println("B-有参构造");
}
}
public class Test{
public static void main(String[] args){
new B(10);
}
}
运行结果:
A-无参构造
B-无参构造
B-有参构造
概念:父类引用指向子类对象,从而产生多种形态。
Animal a=new Dog();
二者具有直接或间接的继承关系时,父类引用可指向子类对象。
父类引用仅可调用父类所声明的属性和方法,不可调用子类独有的属性和方法。
多态中的方法覆盖:
如果子类中覆盖了父类中的方法,以父类型引用调用此方法时,优先执行父类还是子类中的方法?
如果子类覆盖了父类中的方法,则执行子类中覆盖后的方法,否则执行父类中的方法。
多态的应用:
- 使用父类作为方法形参实现多态,使方法参数的类型更为宽泛。
- 使用父类作为方法返回值实现多态,使方法可以返回不同子类对象。
父类引用中保存真实子类对象,成为向上转型(即多态核心概念)。
注意:近可调用父类中所声明的属性和方法。
class Animal(){
public void eat(){
System.out.println("动物在吃...");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗在吃骨头...");
}
}
public class Test{
public static void main(String[] args){
Animal a = new Dog();
}
}
向下转型(拆箱)
向下转型的前提是有向上转型
将父类引用中的真实子类对象,强转回子类本身类型,成为向下转型。
注意: 只有转换回子类真实类型,才可调用子类独有的属性和方法。
class Animal(){
public void eat(){
System.out.println("动物在吃...");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗在吃骨头...");
}
}
public class Test{
public static void main(String[] args){
Animal a = new Dog();
Dog dog=(Dog)a;
}
}
类型转换异常
向下转型时,如果父类引用中的子类对象类型和目标类型不匹配,则会发生类型转换异常java.lang.ClassCastException
class Animal(){
public void eat(){
System.out.println("动物在吃...");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗在吃骨头...");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫在吃鱼...");
}
}
public class Test{
public static void main(String[] args){
Animal a = new Cat();
Dog dog=(Dog)a;
}
}
instanceof关键字
向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性。
语法:引用 instanceof 类型 //返回boolean类型结果
public class Test{
public static void main(String[] args){
Animal a = new Cat();
if(a instanceof Dog){
Dog dog=(Dog)a;
dog.eat();
}else if(a instanceof Cat){
Cat cat=(Cat)a;
cat.eat();
}
}
}
总结
封装:私有属性,get/set
继承:子类父类 extends
多态:父类引用 new 子类的对象



