面向对象
1.什么是面向对象及其热点
面向对象:将构成问题的事务按照一定的规则划分成多个独立的对象,然后通过调用对象的方法来解决问题
面向过程:分析出解决问题需要的步骤,然后用函数把这些步骤一一实现,使用的时候调用就可以了
面向对象的特点:
1.更符合人们日常生活中的行为习惯
2.将复杂的事情简单化(指挥一个具体的事务完成事情)
3.角色发生了变化,从执行者变成了指挥者
面向对象的设计原则: 其实就是在管理和维护对象与对象之间的关系
面向对象的特征: 继承 封装 多态
2.对象
类: 描述一组事务和属性的集合,是java中最基本的单元
对象:描述事务最具体的东西
2.1 类的定义格式
修饰符 class 类名 {
//成员变量
//成员方法
//构造器
//内部类
//代码块
}
2.2创建对象的格式
类名 对象名 = new 类名 ();
访问成员变量
对象名.成员变量
调用成员方法
对象名.成员方法名();
3.封装
概念:将对象的属性和行为封装起来,仅提供对外的公共访问方式
关键字:private:被private修饰的成员只能在本类中访问
类的成员:
成员变量 构造方法 成员方法
匿名对象:没有名字的对象
1.匿名对象可以作为实际参数
2.匿名对象的特点:创建完毕,使用完以后就变成垃圾了,等待GC垃圾回收器回收
3.实际开发中,匿名对象使用一次即可
this关键字的引入:
当局部变量和成员放啊一致时,防止局部变量隐藏成员变量 提供了this关键字
this关键字代表当前类的对象的地址值引用
使用this调用类的构造方法时
1.只能在构造方法中使用this调用其他构造方法,不能在成员方法中使用
2.使用this调用构造方法的语句必须是该方法的第一条语句,且只能出现一次
构造方法:(属于类中的一个成员)
1.没有具体的返回值类型
2.连void都没有
3.方法名和类名相同
通过构造器可以返回一个类的对象,同时可以帮我们把对象的行为属性等初始化好
一个标准类的规则:
1)成员变量私有化,使用private进行修饰
2)提供无参构造方法,有参构造方法
3)提供对外公共的访问方法
4)在测试类中创建对象
static关键字
static 的特点:
1.被static修饰的成员变量被类的所有对象所共享
2.随着类的加载而加载
3.优先于对象存在
4.被static修饰的成员变量和成员方法,可以直接被类名调用
static注意事项:
1.static是没有this关键字的,因为静态优先于对象存在
2.静态只能访问静态的成员变量和成员方法
代码块
局部代码块 :是在局部位置定义,(方法中定义),作用:限定变量的生命周期
构造代码块:在类中的成员位置:每次创建对象都会调用一次,但是优先于构造函数执行,对对象进行初始化
静态代码块:在类中的成员位置 作用:给类中进行初始化! 只执行一次!
在{}前面使用static关键字修饰
静态代码块,构造代码块,构造方法的执行顺序?
静态代码块 > 构造代码块 >构造方法
public class CodeBolck {
static {
System.out.println("静态代码块");
}
{
System.out.println("构造代码块");
}
public CodeBolck() {
System.out.println("构造方法");
}
public void function() {
System.out.println("普通代码块");
}
public static void main(String[] args) {
System.out.println("这是main方法");
new CodeBolck().function();
}
}
静态代码块
这是main方法
构造代码块
构造方法
普通代码块
4.继承
概念:将多个类中的共有属性和公有方法抽取出来,形成一个独立的类,让当前类和其他类之间产生一种关系
关键字:extends
格式:class A extens B
子类也叫派生类
继承的好处:
1.提高了代码的复用性
2.提高代码的维护管理性
3.让类和类之间产生一种关系(是多态的前提条件)
java中的开发原则
高内聚,低耦合
耦合:类和类之间的关系
内聚:指的是完成一件事情的执行能力
java中继承的特点:
在java语言中,继承只支持单继承,不支持多继承,但是可以多层继承
继承中的注意事项:
1.子类不能继承父类的构造方法,因为子类有自己的构造方法
2.子类是可以继承父类的私有成员的,但是无法直接访问,要通过gettet或者setter方法,或者super关键字
3.继承描述的是一种is a 的关系,A 是B的一种,或者B是A的一种,使用继承关系
4.1 继承中子类和父类的变量问题
子类的成员变量名称和父类成员变量名称不一致:
1)通过子类调用成员方法分别输出对应父类的成员变量和子类的成员变量.
当子类的成员变量名称和父类的成员变量名称一致的情况下:
1)首先在子类的局部位置中找,有就输出,没有---->到成员位置找
2)找到了,就输出--->如果子类的成员位置找不到
3)到父类中的成员位置中找,有就输出,
4)如果父类的成员位置找不到,就报错了...
4.2 继承中关系中构造方法的初始化
1)子类的无参构造方法/有参构造方法,都会默认访问父类的无参构造方法...
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始 化。(分层初始化)
每一个构造方法的第一条语句默认都是:super()
4.3 继承中的注意事项
子类的构造方法(无参 有参)会默认访问父类的无参构造方法:
如果父类中没有提供无参,会出现编译不通过(父类提供有参,系统就不会给父类提供无参)
如何解决?
答:给出父类的无参构造方法
在子类的构造方法中通过super()间接的访问父类的有参构造
在子类的有参构造方法中,可以通过this()访问当前子类的无参构造方法
this.成员变量 :访问本类中的成员变量
supre.成员变量:访问父类中的成员变量
继承中的初始化问题
需要先让父类进行初始化,因为子类可能要用到父类的数据
代码块的执行顺序
静态代码块 > 构造代码快 > 构造方法代码块
静态随着类的加载而加载
静态相关的代码块 / 变量 / 成员方法 / 先随着类的加载进行初始化
public class Fu {
static {
System.out.println("静态代码块Fu") ;
}
{
System.out.println("构造代码块Fu") ;
}
public Fu(){
System.out.println("构造方法Fu") ;
}
}
public class Zi extends Fu {
static {
System.out.println("静态代码块Zi") ;
}
{
System.out.println("构造代码块Zi") ;
}
public Zi() {
System.out.println("构造方法Zi") ;
}
public static void main(String[] args) {
System.out.println("main方法Zi") ;
new Zi();
}
}
静态代码块Fu
静态代码块Zi
main方法Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
继承中的初始化
1.初始化父类中的静态成员变量和静态代码块
2.初始化子类中的静态成员变量和静态代码块
3.初始化父类的普通成员变量和代码块,再执行父类的构造方法
4.初始化子类的普通成员变量和代码块,再执行子类的构造方法
4.4 方法重写和方法覆盖
方法重写(override):子类重写父类方法
1.子类在重写父类方法时,方法名,参数列表必须完全一致,返回值类型必须是原来的返回值类型或者其子类
2,子类重写父类方法时,抛出的异常不能大于父类抛出的异常
3.子类的访问权限不能低于父类的访问权限
4.静态的方法只能重写静态
方法覆盖(overload):方法名相同,参数列表不同,与返回值没有关系
4.5 final关键字:最终的,终态的
final修饰的类无法被继承
final修饰的变量是常量
final修饰的方法不能被重写
final修饰引用数据类型,当前该类的对象的地址值不能被改变
面试题:final,finalize,finally的区别?
final是一个关键字,被修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是常量
finalize:是Object类中的一个方法,当对象不被更多的引用指向时,由垃圾回收机制调用该方法
finally:try{}catch{}finally:语句块中,通常用于释放资源,关闭连接
4.6 继承的好处
1.提高了代码的复用性
2.提高了代码的维护管理性
3,让类和类之间产生一种关系
java的开发原则:
高内聚,低耦合
内聚:完成一件事情的执行能力
耦合:类与类之间的关系
5 .多态
概念:不同对象调用同一个方法时,呈现出的不同行为
5.1 多态的签体条件
1.必须要有继承,没有继承,没有意义
2.必须有方法重写,在继承关系中,父类比较抽象
3.父类引用指向子类对象
格式: 父类名 对象名 = new 子类名();
5.2 多态中成员访问特点
成员变量:编译看左边,运行看左边
构造方法:在多态中,父类对象的创建时通过new 子类名(),优先让父类进行数据初始化
成员方法(非静态):
编译看左边,运行看右边
静态的成员方法:(静态成员方法算不上方法重写,因为静态跟类有关系)
编译看左边,运行看左边
5.3 多态的弊端
多态中无法直接访问子类的特有功能
解决办法:
1.直接new子类对象,虽然可以,但是从内存角度考虑,比较消耗内存空间
2.向下转型:将父类引用强制转化为子类对象
例如
Animal a = new Cat()
Cat cat = (Cat)a
6.抽象
概念:在定义一个类的时候,实际上就是把一类事务的共有属性和行为提取出来,形成一个物理模型,这种研究问题的方法称为抽象
抽象类体现的是模板思想,模板是通用的东西抽象 类中已经是具体的实现(抽象类中可以有成员变量和实现方法),而模板中不能决定的东西定义成抽象方法,让使用模板(继承抽象类的类)的类去重写抽象方法实现需求,这是典型的模板思想
6.1 抽象类的特点
1.一个类要被定义为抽象类,必须有abstract关键字
2.如果一个类中有抽象方法,这个类一定是抽象类
什么是抽象方法:只是给一个方法说明,不做具体的体现 public abstrct void method();
3.抽象类中不一定要有抽象方法
4.抽象类不能被实例化,通过抽象类的子类进行实例化
5.抽象类的子类,必须重写父类中抽象方法
abstract和哪些关键字冲突
private 被private修饰的成员方法不能被继承,而abstract修饰的方法要经过子类重写
static 被static修饰的方法可以被类名,方法名直接调用,但是抽象方法没有实现体,调用无意义
final: 被final修饰的方法不能被重写,而抽象方法是强制子类重写
7.接口
概念:体现事务的一种扩展功能
关键字:interface
7.1 接口特点
1)定义接口:
格式:interface 接口名{...}
2)接口的实现类的格式:
class 子实现类名 implements 接口名{}
3)接口中的方法:
只能是抽象方法
4)接口不能实例化 ,如何实例化呢?
a)如果接口的子实现(implements)类是一个抽象类,那么没有意义.
b)接口的的子实现类是一个具体类,可以接口多态的形式创建对象(实例化)
接口名 对象名 = new 子类实现类名() ;
7.2 抽象类和接口的区别
抽象类: 成员变量 既可以是变量也可以是常量
构造方法,存在,可以是有参方法,也可以是午餐方法
成员方法:可以是抽象方法,也可以是具体的方法
接口: 成员变量:只能是常量,默认修饰符:public static final
构造方法:没有构造方法
成员方法:只能是抽象方法,默认的修饰符 public abstract
关系区别:
类与类之间的关系是一种is a的关系,什么是什么的一种
接口与类之间的关系是一种like a的关系,表示的是一种扩展关系
继承关系:单继承
实现:一个类继承另一个类的同时可以实现多个接口
8.形参和实参
形式参数 引用类型:
具体类:都需要创建该具体类的对象
抽象类:如果方法的形式参数是抽象类类型,那么调用方法的实际参数需要该抽象类的子类对象
接口:如果方法的形式参数是接口类型,那么调用方法的实际参数需要该接口的子实现类对象
返回值研究:
基本类型:四类八种 是什么类型就是什么类型
引用类型
具体类:如果方法的返回值类型是具体类,需要返回的是该类的具体对象
抽象类:如果方法的返回值是一个抽象类类型,需要返回的是该抽象类的子类对象
接口:如果方法的返回值是一个接口类型,需要返回该接口的子实现类对象!
9.权限修饰符
访问控制级别由小到大
private default protected public
同一类中 同一类中/同一包下 同一类/同一包/子类 全局范围
10.内部类
10.1成员内部类
public class InnerClass {
class nihao{
public void function() {
System.out.println("nihao");
}
}
public static void main(String []args) {
InnerClass.nihao a = new InnerClass().new nihao();
a.function();
}
}
成员内部类的访问特点
外部类名.内部类名 对象名 = 外部类对象.内部类对象
例如:Outer.inter oi = new outer().new Inter();
10.2 静态内部类
public class InnerClass {
static class nihao{
public void function() {
System.out.println("nihao");
}
}
public static void main(String []args) {
InnerClass.nihao a = new InnerClass.nihao();
a.function();
}
}
static:
静态的成员内部类只能访问外类的静态数据
静态的成员内部类要访问成员
格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
10.3 局部内部类
public class InnerClass {
class nihao{
public void function() {
System.out.println("nihao");
}
}
public static void main(String []args) {
class nihao{
public void function() {
System.out.println("nihao");
}
}
nihao a = new nihao();
a.function();
}
}
1)可以访问外部类成员,包括私有
2)在外部类局部位置可以去访问局部内部类成员,创建该内部类对象,使用对象访问
先在外部类的局部创建内部类对象 再创建外部类对象
当前局部内部类访问局部变量;在内存中已经被fianl修饰
10.4 匿名内部类
匿名内部类:
前提条件:存在一个类或者一个接口
类可以是抽象类也可以是具体类
格式: new 类名或者接口名(){};
本质:是一个继承了类或者实现了接口的子类匿名对象
public interface JioKou {
void eat();
}
public class JieKouImpl{
public static void main(String []args) {
JioKou jj = new JioKou() {
public void eat() {
System.out.println("毛毛吃肉");
}
};
jj.eat();
}
}