一、封装性
引入:使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。
1.概念
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。
2.主要功能
能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
3.封装原则
将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。
4.封装的实现
为属性封装:private 属性类型 属性名称;
为方法封装:private 方法返回值 方法名称(参数列表){}
示例:
//测试类
public class SuccessionTwo {
public static void main(String[] args) {
SuccessionOne s = new SuccessionOne(19,"sdf");//通过构造器初始化对象属性
System.out.println(s.getAge());
//s.age = 10;age权限private,只能在类的内部访问,此时所在位置在同一个包的不同类
s.setAge(10);
System.out.println(s.getAge() + "," + s.getName());
}
}
//封装类
public class SuccessionOne {
//封装属性
private int age;
private String name;
public SuccessionOne() {//构造器
age = 18;
}
public SuccessionOne(int a,String b) {//构造器
age = a;
name = b;
}
void setAge(int i) {
if(i >= 0 && i <= 130) {
age = i;
return;
}
System.out.println("输入有误!");
}
int getAge() {
return age;
}
String getName() {
return name;
}
}
二、继承性
继承减少了代码的冗余,提高了代码的复用性;
便于功能的拓展;
为之后多态性的使用,提供了前提;
1.格式
继承格式:class A extends B{}
A:子类、派生类、subclass
B:父类、超类、基类、superclass
体现:
(1)一旦子类A继承了父类B以后,子类A中就获得了父类B中声明的所有的属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类后,仍认为获取了父类中私有的结构,只是因为封装的影响,使得子类不能直接调用父类的结构而已。
**(2)**子类继承父类 以后,还可以声明自己特有的属性或方法:实现拓展功能。
2.关于继承性的规定
- 一个类可以被多个子类继承;
- Java中类的单继承性:一个类只能有一个父类;
- 子类直接继承的父类,称为:直接父类。间接继承的父类称为:简介父类;
- 子类继承父类后,就获取了直接父类以及所有间接父类中声明的属性和方法;
- 子类不继承父类中的构造器但可以调用;
public class abstractTest {
public static void main(String[] args) {
child a = new child(1,true);
a.introduce();
a.eat();
}
}
abstract class people {
int age;
boolean sex;
//构造器
public people(int age,boolean sex) {
this.age = age;
this.sex = sex;
}
//抽象方法
public abstract void eat();
public abstract void introduce();
}
class child extends people {
public child(int age,boolean sex) {
super(age,sex);//因为父类没有无参构造器,所以必须显示调用父类有参构造器,
System.out.println("sdf");
}
public void eat() {
System.out.println("吃健康的");
}
public void introduce() {
System.out.println("age:" + age + ";sex" + sex);
}
}
注:
Java只支持单继承和多继承,不允许多重继承:
- 一个类只能有一个父类
- 一个父类可以派生多个子类
3.有关Object类
- 如果没有显示的声明一个类的父类的话,则此类继承于java.lang.Object类;
- 所有的Java类(除java.lang.Object类之外)都直接或间接的继承于Java.lang.Object类;
- 即,所有Java类具有java.lang.Object类声明的功能。
4.方法的重写
在子类中可以根据需要对父类中继承来的方法进行改造,也称为方法的重置、覆盖。在执行程序时,子类的方法将覆盖父类的方法。
权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
//方法体
}
要求:
1.子类重写的方法必须和父类被重写的方法具有相同的方法名称和参数列表;
2.子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限;
3.子类不能重写父类中声明为private权限的方法;
4.子类方法抛出的异常不能大于父类被重写方法的异常
**5.**子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型:
(1)父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void;
(2)父类被重写的方法的返回值类型是A类型时,则子类重写的方法的返回值类型可以是A类或A类的子类;
(3)父类被重写的方法的返回值类型是基本数据类型,则子类重写的方法的返回值类型必须是相同的基本数据类型;
注:子类和父类中的同名同参数的方法要么都声明为非static(考虑重写),要么都声明为static的(不是重写)。
三、多态性
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)。
1.引入
Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时看左边;运行时看右。
若编译时类型和运行时类型不一致时,就出现了对象的多态性。
多态情况下:
“看左边”:看的是父亲的引用(父类中不具备子类特有的方法)
“看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)
2.多态的使用前提
- 类的继承关系;
- 方法的重写;
- 对象的多态:只适用于方法,不使用于属性。
3.方法的虚拟调用
有了对象的多态以后,我们在编译期,只能调用父类中声明的方法,但在运行期间,我们实际执行的是子类重写父类的方法。
总结:编译,看左边;运行,看右边。
(1)正确的方法调用
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
(2)虚拟方法调用
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。(动态绑定)
4.向下转型
引入:如何才能调用子类所特有的属性和方法? 答:向下转型
向下转型:使用强制类型转换
A a1 = new B();
B b1 = (B)a1;
四、抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类;抽象来除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法、初始化块和构造方法和普通类一样。由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
1.概念
- Java中可以定义被abstract关键字修饰的方法,这种方法只有声明,没有方法体,叫做抽象方法.
- Java中可以定义被abstract关键字修饰的类,被abstract关键字修饰的类叫做抽象类.
2.抽象方法
- 抽象方法只有方法的声明,没有方法体;
- 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
- 包含抽象方法的类一定是一个抽象类,反之,抽象类中可以没抽象方法;
3.抽象类
使用原则:
- 此列不能实例化;
- 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程);
- 开发中,都会提供抽象类的子类,让子类对象实例化,完成想过操作;
- 若子类重写了父类中所有的抽象类后,此类可以实例化;若子类没有重写完父类中的所有的抽象方法,则此类也是一个抽象类,需使用abstract修饰。
4.注意
- abstract不能用来修饰:属性、构造器等结构;
- abstract不能用来修饰私有方法、静态方法、final的方法、final的类;
abstract class A{//定义一个抽象类
public void fun(){//普通方法
System.out.println("存在方法体的方法");
}
public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类
@Override
public void print() {//强制要求覆写
System.out.println("Hello World !");
}
}
public class TestDemo {
public static void main(String[] args) {
A a = new B();//向上转型
a.print();//被子类所覆写的过的方法
}
}