权限访问修饰符
这里讨论的范围有,类,同一个包,子类,不同包
对于public修饰的,那就以上四类都可以
对于protected修饰的,在不同包中不可访问
默认的也就是default修饰的,子类和其他包中不能访问
private修饰的,是权限最少的,只有同一个类中可以被访问,常用于封装,再提供setter和getter方法起到保护数据的作用
规律就是四个修饰符,四个权限范围,从大到小也就是从上到下,每次减少一个权限
什么是面向对象呢
把相关的数据和方法组织为一个整体来看待,让我们在看待程序的时候更加的贴近事物自然运行的模式
对于一个程序员而言,是思想从执行者到指挥者的变化
就一个问题而言,面象过程的解决办法是如何去解决,分哪些步骤去解决
面向对象的解决办法是,找谁去解决,那么就创建可以解决这个问题的对象,就交给这个对象了
EG: 要怎么吃饭?
对于这个场景,面向过程的解决办法是,想,首先去买菜,再烧水,放米,烧油。。。
而对于面象对象的就是,招一个保姆,保姆去解决
现在将这个问题放大,如果是一个土豪,每天除了要吃饭,还要修建,要浇水,要搞卫生。。。
这个时候,如果是面向过程的思维,就是要先这样,再这样。。。等等等等一大堆,举都举不完,栗子太多了
所以就显得不合理,就体现出了面向对象的思维的优势,我就招一个管家,让管家去处理,管家还能再招聘工人,保姆等等
面向对象的三大思想是
OOA : object oriented analysis ——面向对象分析
OOD : object oriented design——面向对象设计
OOP : object oriented programming——面向对象程序
面向对象的三大特征: 封装,继承,多态
类和对象的关系:
类就是共性的产物,是一个综合特征,对象是一个个性的产物,是从类中抽象出来的一个个具体的实例
比如有个汽车类,那就是一个综合的,四个轮子的,地上跑的,就是汽车,很大的一个概念,
对象就具体了,比如牌子叫宝马,型号是XXX,车牌照XXX,颜色XX等等
然后,类要通过对象才能进行使用,对象的所有操作都是在类中定义的
类是由属性和方法组成的,对象在使用的时候就是调用的这些个属性或者方法来具体化自身
对象创建过程中的内存的分析
创建的对象会被存储在栈内存空间中,而new过了的就会在堆内存中为其开放一块空间,有唯一的地址,栈中的对象根据该地址找到该空间
如果改变了类中定义的属性,那么就会在堆内存中相应的改变,
假设已经建立了 Book book = new Book();
现在用Book book2 = book;
也就是说现在book2指向的地址就是book1在堆内存中的地址
所以现在如果用book2对类的属性进行操作改变,是相对的堆中的地址进行了改变
而现在的book指向也还是堆中的那块地址,所以这不是一个简单的复制过程,内部的逻辑也需要理清楚
Java类中至少会有一个构造方法,也就是常说的构造器
如果没有明确的定义构造方法,系统会自动生成一个无参的构造方法(不推荐依赖此方法)
Java允许出现同名函数,这就是方法的重载
判断是否重载的方法:1.方法名是否相同 2.参数是否不同(具体体现在,类型和长度上)
对于静态修饰符Static
静态的数据会被存放在方法区中,在类被第一次加载的时候使用,可以看成是类的具体属性,而不是对象的具体属性
比如汽车店中,那么他有车,有这种那种车,那是具体的对象,对于车而言的,那么如果是卖出去了多少车,那么就是对于店而言的
用static修饰,可以通过类名.static修饰的方法或属性直接调用,
要注意
静态方法在被调用的时候,有可能还没有创建具体的对象,也就是说,没有创建对象,也可以直接通过类来调用修改static的值
但是,静态不能访问非静态,非静态可以访问静态
因为非静态可用,就说明对象已经创建,对象已经创建就说明类已经被加载,那么类呗加载就肯定能用静态的了
就像现在2020年你不能找2030年的人玩,他还没出生,但是到了2030年,他就能找你2020年的人来玩
关于代码块的问题
普通代码块,那就是普通大括号包起来的部分,写在方法里,没什么特殊的
构造代码块,写在类中,直接大括号包起来,在对象被创建的时候被调用,执行在构造方法之前
静态代码块,就是添加了static修饰符的代码块
staic{
}
这种代码块在类被加载的时候,就是第一次使用的时候而执行,因为类的加载只一次,所以这个代码块的执行也只一次
面试题:
执行顺序是?
静态——》构造代码块——》构造方法 很明显,在对象的创建之前,就需要把类加载到内存,所以静态代码块会先执行
继承
在类与类之间的共同点很多的时候,写多个类就导致代码的复用性比较差,所以引入了继承的概念
class 子类名字 extends 父类名字{
}
在父类中有的东西(除了一些私有的或者默认的没有访问权限的除外),都可以被子类拿来用
java中只有单继承和多重继承,没有多继承(即一个子类不能有多个父类),这是为了防止在继承的时候父类中的东西如果有重复而导致不知道继承哪边而造成问题
如果c又想继承A又想继承B,那就让c继承B让B继承A,这样多重继承的形式实现
内存分析
super关键字
通过调用super构造方法,super必须写在子类构造方法的第一行,不能和this连用
父类可能有N个构造方法,默认是通过无参的构造方法来访问,如果父类中没有无参的构造方法,就必须子类用super调用。
重写和重载
重写发生在类的继承,如果子类想有自己的方法,而不是去调用到父类的方法,这个时候就要把父类的方法在子类中重写一遍,(方法体不同),
这样在子类中的方法就会生效,父类中的方法就不会生效,这样的就是重写
规则:
- 参数列表必须和被重写的完全相同
- 返回值类型相同
- 访问权限不能比被重写的时候的方法的访问权限低
- 父类的成员方法只能被它子类重写
- 声明为static和private的方法不能重写,但是可以被再次声明
面试题
在java中的重写和重载的区别
- 发生的位置不同,重写发生在子父类中,重载发生在同一个类中
- 参数列表的限制不同,重写要求参数列表相同,重载要求不同
- 返回值类型限制不同,重写要求返回值类型相同,重载要求不同
- 访问权限要求不同,重写要求重写的函数不能比被重写的函数访问权限低,重载都可以
- 异常处理的方式不同,重写要求异常更少或者删除(异常的范围可以更小,但是不能抛出新的异常),重载与异常无关
final关键字
final关键字修饰的变量会变成常量,无法再次赋值,可以刚开始只声明而不赋值,但是后续也只能赋值一次
如果final修饰的是成员属性,则必须再声明时赋值
public static final 修饰的为全局常量
常量的命名规范 ; 单词与单词之间用下划线隔开,单词中的需哦有字母大写
如果是用final修饰的类,那么这个类就无法被继承,final修饰的方法无法被子类重写
关于抽象类
声明方式: abstract classs
抽象类不能被实例化,即不能用new关键字,
所以抽象类必须被子类给继承,不然就没有意义
子类(不是被定义为抽象类的)就必须重写抽象父类中的全部的抽象方法
在抽象类中不能定义静态的抽象方法,抽象类不能被实例化,所以就不能分配内存,而static修饰的在实例化之前就已经分配了内存,就矛盾了
抽象类不能用final修饰,final修饰的不能被继承,没有子类的抽象类没有意义
抽象类可以有构造方法,子类在实例化的时候和普通类一样,都会调用父类的构造方法,默认无参构造方法
抽象类和普通类的区别
- 抽象类必须由public或者protected来修饰,默认情况下为public
- 抽象类无法用new实例化,但是在子类实例化的时候,抽象类会被JVM给实例化,程序员无法操作
- 子类必须实现父类所有的构造方法,除非子类也被定义为抽象类
关于接口
如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么就可以吧这个类定义为一个接口
interface 接口名称{
全局常量;
抽象方法;
}
在继承时候使用implements关键字
- 接口和抽象类的区别
- 抽象类要被子类继承,接口要被实现
- 接口中只能声明抽象方法,抽象类中可以声明抽象方法也可以声明非抽象的方法
- 接口中定义的变量只能是公共的静态常量,抽象类中可以定义普通变量
- 接口可以多实现,类不能多继承
- 接口中不能有静态方法,静态方法不能被子类重写
- 接口不能有构造方法
接口不是被继承,所以在子类被实例化的时候也不会被JVM创建
多态
java中有多态的概念,就是对象的多种表现形式
对象的多态性:一个父类可以中多个子类,每一个子类就是父类的不同的形态
方法的多态性:主要体现就是方法的重写和重载
Object类是所有类的父类
关于内部类
成员内部类:
成员内部类可以无条件的访问外部类的所有属性和成员方法,包括私有的
局部内部类;
当有一个方法要用到Person对象,但person对象中有一个方法没有被实现过,现在如果只要用到一次该方法
要先去创建一个类,就比较麻烦,所以就用局部内部类,为了实例化一个对象来实现该方法
匿名内部类:
只能用一次的
Person p = new Person(){
未实现的类;
}
注意点:
- 匿名内部类在使用的时候,必须继承一个父类或者实现一个接口,不可兼得
- 匿名内部类中不能定义构造方法
- 匿名内部类不能有静态成员变量或者静态方法
- 匿名内部类为局部内部类,所以局部内部类的限制条件都是匿名内部类的限制条件
- 匿名内部类不能是抽象的
- 只能访问final型的局部变量
int i = Integer.parseInt(“100”);
包装类,可以实现字符串和基本数据类型之间的转换