java封装,继承,多态
封装
封装:隐藏内部细节
成员变量:建议用private;
用getter和setter方法去访问它
封装用【访问修饰符】来实现,表示封装的不同程度。
private: 在【本类】里能直接访问;其他类用getter和setter访问。
默认:在【本包】里能直接访问;
protected:在【本包】里能直接访问;【外包】子类可以直接访问;
public:在【本包】【外包】能直接访问(即在整个项目里能直接访问);
四个访问修饰符可以修饰:成员变量,成员方法;
修饰 类 只能用两个访问修饰符:public和默认;
类:public class HelloWorld{}
class HelloWorld{}
封装的好处:隐藏内部实现细节;
1.从程序的角度:安全;
2.从用户的角度:简单;
继承
1.Object是所有类的顶层父类;
如果没有显式地继承父类,默认继承了Object类。
3.一次只能继承一个类;
可以多层继承。
*继承的语法:extends
public class Dog extends Animal {…}
Animal:父类,基类,超类;
Cat,Dog:子类,派生类;
*继承的好处:
把子类里共同的代码提取到父类里:节省代码,便于代码重用。
父类有改变,子类都会改变。
子类可以调用父类的成员。
如果父类的方法不满足子类需要,子类可以【重写】。
重写的规则:
1)方法名必须相同;
2)参数列表必须相同;
3)访问修饰符 不小于 父类的访问权限; 不小于
4)返回值类型: 必须和父类的一致或父类返回值类型的子类; 不大于
5)抛出异常的类型: 必须和父类的一致或父类抛出异常的类型的子类; 不大于
重载:
1)同一个类里;
2)方法名必须相同;
3)参数列表必须【不同】;
4)访问修饰符,返回值类型,抛出异常的类型:不影响。
重写:
1)两个类:父类和子类,继承关系;
2)方法名必须相同;
3)参数列表必须【相同】;
4)访问修饰符:不小于;
返回值类型,抛出异常的类型:不大于。
*继承条件下构造方法的执行顺序
*1.调用子类的构造方法,默认会调用【父类无参】的构造方法。
public Dog() {
super();//如果不写也会调用父类无参;
System.out.println("子类 无参");
}
2.继承条件下构造方法的执行顺序是:层层向上调用构造方法,直到顶层父类Object,再层层往回执行完每个构造方法。
*3.如果显式调用了父类的构造方法,就调用你指定的构造方法。
*4.构造子类对象时一定会调用父类构造方法。
*继承条件下代码块的执行顺序:
*父类静态代码块—>子类静态代码块—>父类 非 静态代码块—>父类构造方法—>子类 非 静态代码块—>子类构造方法
*super关键字:super【直接】父类对象
super和this表示构造方法时必须放在第一句,不能同时调用super和this构造方法。
super是引用变量,指向直接父类。
//没学多态之前:B b=new B();
//多态: A a=new B();
// A a1=new C();
*
B b=new B();//b可以调用子类特有的方法;
*A a=new B();//a只能调用父类里定义过的,被子类重写的方法。
*
*4.父类引用调用被子类重写的方法;
*运行时多态:运行时才确定调用哪个子类的方法。
*
*
*/
*类型转换:
1)基本数据类型转换:自动转换和强制转换;
2)引用数据类型转换:向上转型和向下转型;
引用数据类型转换:
向上转型;自动转换;
Animal an1=new Dog();
2)向下转型;强制转换;
Dog dog2=(Dog)an2;
1>向下转型:父类引用必须转成【父类真实指向的子类型】,否则会报强转异常:java.lang.ClassCastException: com.sxt.oop.cast.Dog cannot be cast to com.sxt.oop.cast.Cat
2>也就是说,向下转型之前肯定进行过向上转型了。
对象名 instanceof 类名(接口名)
4)对象名 instanceof 类名(接口名)
对象名所属的编译类型和类名在同一继承树上的上下级关系,才不会报错。