面向对象的三大特征
访问权限修饰符
访问权限修饰符:
在Java语言中,一切事物(类所有成员)都具有(或显示定义或隐式定义的)访问权限,而这种语言层面的访问权限控制,是由访问权限修饰符实现
访问权限修饰符的访问控制,
1、修饰类中成员(field & method)
控制类中的成员,对其他类可见性(其他类是否可以直接使
用到)
public:
任意类均访问,实际就是没有限制访问权限
protected:
同包中的其他类,和不同包的(可见)子类均可见
default(默认权限,隐式定义):
同包中的其他类可见
private:
仅对同类中的其他成员可见
public | protected | default | private | |
---|---|---|---|---|
同一类中 | √ | √ | √ | √ |
同一包子类,其他类 | √ | √ | √ | |
不同包子类 | √ | √ | ||
不同包其他类 | √ |
能够修饰类的只有public与default
2、修饰类
通常用来限定,类库中的类(自定义数据类型),对于外部使 用者的可见性(是否能使用该类型)。
public:使类具有共有访问权限,在哪里都可以访问这个类
protected:不能修饰类
default:只有同包中的类才能访问默认权限中的类
private:不能修饰类(并非所有的类,有一种特殊的类可以修饰)
面向对象3大特征之封装
封装:
是一门种信息隐藏技术
1、是指将数据和基于数据的操作封装在一起
2、数据被保护在内部
3、系统的其他部分只有通过在数据外面 的被授权的操作才能够进行交互
4、目的在于将类使用者class user和类设计者class creator分开。
get方法
getXxx()//得到类中private的值
public int getXxx(){return Xxx;}
setXxx()//修改类中private的值
public void setXxx(int Xxx){this.Xxx=Xxx;}
面向对象3大特征之继承
继承
1、Java中的继承和我们现实生活中的“继承”的含义基本类似,但是含义更广。
2、被继承的类称之为父类(基类,超类)继承其他类的类称之为子类(派生类,导出类)。
3、子类可以通过继承机制,不写任何额外代码就可以拥有父类的“所有”成员。
语法
class 子类名 extend 父类名 {}
优点
代码复用(方法,类)
提高了代码的可维护性(这是一把双刃剑)
弱化java中的类约束(可以让父类引用指向子类对象)(多态的前提)
缺点
父类的修改可能会出现在所有的子类中(我们无法选择这些修改可以反应在,哪些子类中,不可以反应在哪些子类中)
注意事项
子类只能访问父类所有非私有的成员(成员方法和成员变量)
子类不能继承父类的构造方法
子类对象的初始化
隐式初始化(jvm自动保证)
当父类提供了默认的构造函数,且子类的构造函 数中没有显式调用父类的其它构造函数,则在执行子类的构造函数之前会自动执行父类的构造函数 ,直到执行完父类的构造函数后才执行子类的构造函数。
注:父类没有无参构造方法,则不用使用隐式初始化
显示初始化(通过写代码的方式来保证)
运用super在子类构造函数的第一条语句调用父类的默认构造方法或者特定签名的构造函数:super(Xxx);
注:this 与super不能共存,且位于构造方法的第一行
域的隐藏
子类中定义和父类中同名的成员变量,在子类中调用,访问的是子类定义的同名变量的值,在父类中调用,访问的是父类定义的同名变量的值
class father(){
int value==23;
public void out(){
System.out.println(value);
}
}
class son extends father
{
int value=99;
public void AllAccess(){
\\直接访问子类定义的同名变量
System.out.println(value);
\\访问父类定义的同名变量
super.value;
}
}
super.value在子类访问父类
子类的方法访问子类变量
父类的方法访问父类变量
在子类对象中访问成员变量的规则:
在子类中查找,找到则直接访问,没有找到则去父类对象上查找并访问
方法的覆盖或重写
子类中定义和父类中同名的方法,在子类中调用,访问的是子类定义的同名方法,在父类中调用,访问的是子类定义的同名方法,通过super关键字可以在子类中访问到父类的方法(super.same();)
class father{
public void same(){
System.out.println("father");
}
}
class son extends father{
public void same(){
System.out.println("son");
}
}
}
在子类对象中调用方法的规则:
当方法执行的时候优先在子类中寻找,找到则执行,找不到则去父类中寻找
方法覆盖的条件
访问权限 返回值 方法签名:(三部分)
1、访问权限:子类的访问权限不小于父类的访问权限即可。
2、返回值:
基本数据类型的方法返回值:子类必须与父类相同
引用数据类型:
a、子类父类返回值类型相同
b、子类方法返回值类型是父类方法返回值类型的子类类型
3、方法签名一致
注意事项
1、父类中的私有方法不能被覆盖
2、静态方法不能被重写
3、final修饰的方法不能覆盖
final关键字
final是最终的意思,可以修饰类,变量,成员方法。
修饰类:类不能被继承
修饰变量:变量就变成了常量,只能被赋值一次
1、修饰成员变量:必须在定义时初始化
2、修饰局部变量:可以在定义时初始化也可以在构造方法中初始化(在创建对象之前通过代码给初始化)
修饰方法:方法不能被重写
注:
final A obj=new A ();修饰的只是obj这个引用变量,obj中的成员变量可以修改
面向对象3大特征之多态
多态:同一个对象的行为(方法),在不同时刻(条件)表现出来的不同的效果。
多态实现的三个条件
1、继承
2、方法覆盖
3、父类引用指向子类对象(eg:Animal animal = new Dog(); )
成员访问特
成员变量Animal animal=new dog ();
编译看左边(Animal),运行看左边(Animal)(实际运行的效果)
成员方法Animal.eat();
编译看左边(Animal),运行看右边(dog.eat.()😉(实际运行的效果)
优缺点
优点:
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
缺点:
不能访问子类特有功能
解决办法:
把引用变量的类型,改成子类类型(含有特有功能)的引用变量,(父类与子类的转化):
子类类型 引用变量 = (子类类型)父类类型的引用变量
eg:
Animal为父类,Duck为子类
Animal animal=new Animal();
Duck duck=new Duck();
//可以 父类=子类
animal=duck;
//不可以 子类=父类,没办法,只能在必要时进行强制转化
//子类类型 引用变量 = (子类类型)父类类型的引用变量
duck=animal;
instanceof
if (父类 instanceof 子类)
true则表示可以强制转换
//解决强制类型转换可能失败的问题
对象名(对象的引用变量) instanceof 实例类型(目标类的类名)