封装性
我们程序追求的是 高内聚 低耦合 (类的内部数据操作细节自己完成,不允许外部干涉;仅对外暴露少量的方法用于使用)
封装性需要我们配合权限修饰符来进行使用,按照权限的从小到大顺序分别是:
1、private2、缺省3、protected4、public
构造器:任何一个类都有一个构造器(自己不定义就是用默认的构造器(无参)(修饰符和类的权限修饰符相同)) 构造器是可以进行重载的(overload)
注意:
我们在spring中有一个接口是InitializingBean ,实现这个接口就会有一个afterPropertiesSet方法,这个方法用于 在spring创建bean的时候进行自动执行。
执行顺序:
constructor(构造方法)——>@Autowired——>@postConstruct -->实现InitializingBean 中afterPropertiesSet() 方法
赋值的几个位置:
1、默认的初始化()2、显式的初始化()3、构造器初始化4、通过对象的方法进行赋值
5、代码块
执行的顺序为 1 2 5 3 4
什么是默认初始化和显示初始化?
答:默认初始化是系统在堆内存创建一个新的对象时,进行的默认初始化,如null 和0
显示初始化是在类定义时,直接在各个成员变量的定义时,优先进行赋值,这叫显示初始化。
继承性extends:
方便代码的扩展 减少冗余 为多态性提供前提
class A extends B{ }
A:子类、派生类、subclass B:父类 、超类、基类、superclass
子类一旦继承了父类,子类就获取了父类中声明的属性和方法(即使是父类中private修饰的属性和方法我们也会继承 ,只不过不能访问而已)
java不支持多继承(一个类最多一个父类),只可以单继承或者多层继承,我们可以通过接口实现类似多继承的效 果。
子类和父类是相对的,直接继承的叫做直接父类,间接继承的叫做间接父类。一旦继承,子类获取的他所有直接父类 和间接父类的属性和方法。
重写(override):子类中对父类方法的改造
1、子类中重写的方法 要和父类中被重写的方法参数列表、函数名相同
2、子类中重写的方法的 返回值类型 抛出异常的类型 不能大于 父类中被重写方法的 返回值类型 抛出异常类型
3、子类中重写的方法的 访问权限 不能小于父类中被重写方法的 访问权限
注意:子类和父类同名同参数的方法必须同时声明为static或者非static
重载(overload):同一个方法中,存在多个函数名相同,参数类型或者个数不同的现象
子类对象实例化的过程:
结果上来看:子类就获取了父类中声明的属性和方法
过程上来看:当我们通过子类的构造器进行创建子类对象的时候,我们就会直接或者间接的调用父类的构造器,直到 调用到object的构造器为止
虽然我们创建的子类对象的时候我们调用了父类的构造器,但是自始至终我们就创建了一个对象就是子类对象。
多态性:(依赖于implents和extends)
体现为对象多态性-----父类的引用可以指向子类的对象,接口的引用可以指向实现类的对象
(虚拟方法调用):当使用父类的引用执行方法的时候,他执行的是所创建的子类对象重写父类的方法(动态绑定),如果该方法父类中不存在,属于是子类特有的是不可以被调用的(但是可以通过强制类型转换引用类型来调用特有的方法)。
类型为父类的引用,所以无法调用子类特有的类型
package com.geng.duotai;
public class Person {
private String name;
private int age;
public void eat(){
System.out.println("人要睡觉");
}
public void sleep(){
System.out.println("人要睡觉");
}
}
package com.geng.duotai;
public class Woman extends Person {
@Override
public void eat() {
System.out.println("男人要吃饭");
}
@Override
public void sleep() {
System.out.println("男人要睡觉");
}
public void shop(){
System.out.println("女人要逛商场");
}
}
package com.geng.duotai;
public class test {
public static void main(String[] args){
Person person=new Woman();
person.eat();
//无法执行这个方法,因为虚拟方法的调用
// person.shop();
//如果我们要使用这个方法可以通过以下方式
Woman woman=(Woman)person;
woman.shop();
}
}
这其实也是多态性的一种使用,想想经常使用Object当作参数,然后在使用类型转换。这样提高了代码的普适性。
经典问题:多态是编译时的行为还是运行时的行为?
编译时的行为。我也不知道怎么解释,看样例:
package com.geng.duotai;
import java.util.Random;
public class test01 {
static class Animal{
public void eat(){
System.out.println("animal");
}
}
static class Cat extends Animal{
public void eat(){
System.out.println("cat");
}
}
static class Dog extends Animal{
public void eat() {
System.out.println("Dog");
}
}
public static void main(String[] args){
Random random=new Random();
int n=random.nextInt(2);
Animal animal=null;
if(n==1){
animal=new Dog();
}
else{
animal=new Cat();
}
animal.eat();
}
}
向下类型转换:
instanceof操作符:
a instanceof A 判断对象a是否可以为类A的实例
在进行强制类型转换的时候进行判断,防止出现ClassCastException
几种常见的转型错误:
package com.geng.duotai;
import java.util.Random;
public class test01 {
static class Animal{
public void eat(){
System.out.println("animal");
}
}
static class Cat extends Animal{
public void eat(){
System.out.println("cat");
}
}
static class Dog extends Animal{
public void eat() {
System.out.println("Dog");
}
}
public static void main(String[] args){
//可以的:
Animal animal=new Dog();
animal=(Dog)animal;
Dog dog=new Dog();
Animal animal2=dog;
//不可以的:
Animal animal1=new Dog();
animal=(Cat)animal1;
Animal animal3=new Animal();
Cat cat=(Cat)animal3;
}
}