Java基础——面向对象(初级)
三条主线:
类及类的成员:属性、方法、构造器、代码块、内部类
面向对象的三大特征:封装、继承、多态
其他关键字:this、super、abstrct、interface、static、package、import
1.类、对象
类:class,对一类事物的描述,抽象概念定义。(属性/成员变量、方法/函数)
对象:new,实际存在的事物个体,实例。
过程:
创建类,设计类的成员class Person{String name;public void eat(){}}
创建类的对象Person a=new Person();
调用类的属性或方法a.name=""; a.eat();
2.内存解析
虚拟机栈:存储局部变量
堆:对象实例
方法区:被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码
3.变量
属性(成员)变量:
定义在类{}里
0/0.0/false/null
加载到堆空间
局部变量:
定义在方法内
没有默认初始值,需要赋值
加载到栈空间
4.对象数组
定义一个对象数组后,系统只是分配了一个引用空间(只是声明),并没有实际分配内存空间给数组中的元素,因此对象数组中的元素还是需要使用new运算符来实例化 。
person[] a=new person[3]; a[0]=new person();
只有string可以new,也可以不用新建new对象,字符串常量池,string s="hello";
5.匿名对象
6.方法重载
同一个类
同一个方法名
不同的参数列表
跟权限修饰符、返回值无关
7.可变个数形参
数据类型 ... 变量名
string ... a与string[] a相同,可为重写
若有匹配的确定数量参数的方法优先调用
8.变量赋值
基本数据类型:
int a=10;
int b=a;//两个空间,一变另一不变
引用数据类型:
string a=new string();
string b=a;//指向同一个地址,一变全变
9.封装性的体现
将类的属性声明为私有的private,提供公共的public方法来获取(get)和设置(set)此属性的值。(把类的属性设置一个方法权限进行限制制约,使用户无法直接调用,需要调用方法去给属性赋值)
10.权限修饰值
修饰类的内部结构:属性、方法、构造器、内部类
修饰类只能使用缺省、public(构造器与类相同)
private:类内部
缺省:类内部+同一个包
protected:类内部+同一个包+不同包的子类
public:类内部+同一个包+不同包的子类+同一个工程
11.构造器
作用:
创建的对象
初始化对象的属性
说明:
定义构造器的格式:权限修饰符 类名(形参列表){}
创建类的对象:new+构造器(系统默认的空参构造器)
一旦显式定义类的构造器,可以不写空参构造器
但若需要new空参构造器,则需要写默认的空参构造器
12.this
调用属性、方法(this.xxx表示当前对象(类的方法中)或当前正在创建的对象(类的构造器中),方法的形参与类的属性同名时,显式使用this.)
调用构造器(显式this(形参列表)表示,首行,一个)
13.package
管理类
每"."一次代表一层文件目录
java.lang、java.net、java.io、java.util、java.text、java.sql、java.awt
14.import
导入指定包下的类、接口
xxx.*表示导入xxx包下的所有结构
java.lang包/本包的类可省略
使用不同包下的同名类,声明时加上包名
15.MVC
controller控制层=>model模型层=>view视图层
16.继承
class A extend B{}
子类A获取到父类B中的属性、方法,还可以声明自己特有的属性或方法
所有的类都直接或间接继于java.lang.Object类
17.方法重写
子类继承父类以后,对父类中同名同参数的方法,进行覆盖操作。
18.super
调用父类的属性、方法:
子类父类有同名属性或重写方法,调用父类时需要显式定义super.
调用父类的构造器:
super(形参列表)需声明在子构造器的首行
this与super只能选择一个,默认super(形参列表);(所以具有父类的属性和方法)
子类构造器中显式使用super(形参列表)
19.多态性
实现代码的通用性
父类的引用指向子类的对象
编译时,只能调用父类声明过的方法
执行时,执行子类重写的方法
多态性的使用(虚拟方法调用):调用同名同参数的方法,执行子类重写父类的方法
equal(Object a),Object可表示各种数据类型
多态是运行时行为,不是编译时行为
20.instanceof
向下转型:使用强制类型转换符。使父类能使用子类特有的方法。
避免向下转型出现classcastexception异常,使用instanceof判断
a instanceof A:判断对象a是否是类A的实例。如果是,返回ture,如果不是,返回false
21.java.lang.Object
所有类的根父类(多态),无属性,只声明了一个空参构造器。
方法:
equals():
是一个方法,基本数据类型不是对象,只适用于引用数据类型。
在string、Date、File、包装类中重写了该方法,比较的是内容。
自定义类时比较需要重写。
(==:是运算符,基本数据类型比较数据,引用数据类型比较地址值。
自动类型提升:65==65.0f、12(int)==a(char a=12)都返回true)
toString():
输出一个对象的引用(类型+@+地址)时等于调用当前对象的toString()方法
重写toString()
在string、Date、File、包装类中重写了该方法,输出实体内容信息。
getClass()、hashCode()、clone()、finalize()、wait()、notify()、notifyAll()
22.单元测试
JUnit测试:类似main,不用写main
类:public,提供公共的无参构造器
方法:public,无返回值,无形参,方法上声明注解@Text,import org.junit.Test;
23.包装类
将基本数据类型包装为类/引用数据类型
byte=>Byte、short=>Short、
int=>Integer(内部定义了InterCache结构,数组范围-128-127,自动装箱时不用new,提高效率,所以范围内的数指向同一地址)
long=>Long、float=>Float、double=>Double、boolean=>Boolean
char=>Character
24.基本数据类型、包装类与String类型的转换
基本数据类型转换为包装类:
int a=1;
Integer b=a;//自动装箱(JDK5.0新特性)
Integer b=new integer(a);//通过包装类构造器 整型int
包装类转换为基本数据类型:
Integer a=new integer(1);
int b=a;//自动拆箱(JDK5.0新特性)
int b=a.intValue();//调用包装类的方法xxxValue()
String类型转换为基本数据类型、包装类:(自动装/拆箱)
int a / Integer a=Interger.paseInt("1");//调用对应包装类的方法parseXxx(String)(a:基本数据类型)
int a / Integer a=new Integer("1");//通过包装类构造器 字符串String(a:包装类)
基本数据类型、包装类转换为String类型:(自动装/拆箱)
int a / Integer a=new Integer(1);
String b=String.valueOf(a);//调用String重载的String.valueOf方法(a:基本数据类型)
String b=a+"";//基本数据类型+连接运算(a:基本数据类型)
String b=Integer.toString(a);//调用包装类的toString(形参)的静态方法(a:包装类)
String b=a.toString();//包装类的toString()方法(a:包装类)
25.static
可以被多个对象共享的属性 / 通常类中的常量 / 通常操作静态属性的方法 / 工具类中的方法
类的加载-对象加载-对象消亡-类的消亡
静态属性 非静态属性
类 yes no
对象 yes yes
修饰属性:
通过“类.静态属性”调用(存在方法区中)
实例变量、静态变量 (多个对象共享)
随着类的加载而加载,早于对象的创建,
修饰方法:
通过“类.静态方法”调用
静态方法中,只能调用静态方法与属性(main)(因为非静态的属性值未知,需要创建对象赋值)
不能使用this、super(对象的东西都不能使用)
子类与父类同名同参数的方法要么都是static(不是重写),要么都是非static
代码块:
内部类:
26.单例(Singleton )设计模式
只生成一个实例,对某个类只能存在一个对象实例,减少了系统性能的开销。
饿汉式:对象加载时间过长,但是线程安全
私有化类的构造器
私有化创建类的静态对象
提供公共的静态的方法,返回类的对象
懒汉式:延迟对象创建,但是
私有化类的构造器
私有化声明类的静态对象,没有初始化
提供公共的静态的方法,返回类的对象(判断对象是否创建)
27.代码块或初始化块
初始化类、对象,将类里面的操作放在代码块里执行
若有修饰,只能使用stastic{}
静态代码块:
内部可以有输出语句
随着类的加载而执行,而且只执行一次,因为类只加载一次
只能操作静态属性或方法
初始化类的信息
非静态代码块:
内部可以有输出语句
随着对象的创建而执行,每创建一次执行一次
初始化对象的信息
28.属性赋值顺序
默认初始化
显示初始化 / 代码块赋值
构造器中初始化
有了对象以后,通过对象.属性、对象.方法赋值
29.final
修饰类:
不能被继承,如String类、System类、StringBuffer类
修饰方法:
不能被重写,比如Object的getClass();
修饰属性:
赋值位置(显式初始化、代码块、构造器),变成常量
static final用来修饰属性:全局常量
非静态的final可以赋值,每个对象不一样
修饰局部变量:
修饰形参时,表明是常量,调用方法时,声明时赋值,只能在方法体内使用
30.abstract
抽象的,父类无法详细描述
修饰类:
不可被实例化
一定有构造器,子类实例化需要调用super()
修饰方法:
存在抽象类里
只有声明,没有方法体,子类重写后实例化
若子类没有重写父类所有的抽象方法,则子类也要抽象修饰
应用:模版方法设计模式(Template)
31.interface
接口和类并列
不能定义构造器,所以接口不可以实例化(若多个接口都有自己的构造器,则不好决定构造器链的调用次序)
接口定义:
jdk7:
只能定义全局常量
(public static final
可调用常量template.a)
抽象方法
(public abstract;
抽象方法不能调用,需重写)
jdk8:
还可定义静态方法
(static 只能通过接口来调用;
可调用接口类的静态方法template.a();)
默认方法
(default 通过实现类的对象,可以调用接口中的默认方法;
如果实现类重写了默认方法,则调用重写后的方法;
如果子类继承和接口有同名同参数的方法,则没重写条件下使用父类方法;
接口定义同名同参数默认方法,则没重写条件下报错;
可调用接口类的默认方法 template.super.a();)
接口使用:
通过类实现(implements:实现)class A implements B,C
需要覆盖所有抽象方法,否则还是为抽象类
接口与接口之间可以多继承(extends:继承)class A extends B,C
接口应用:
代理模式、工厂模式;体现多态性,只定义一种规范,具体实现给子类做。
抽象类和接口的异同:
相同点:不能实例化,可以包含抽象方法,可以被继承
不同点:抽象类有构造器,单继承;接口不能声明构造器,多继承
32.内部类
将一个类声明在另一个类内
成员内部类:
静态
new Person.Dog();、
调用静态的结构
非静态
Person.Bird bird=new Person();Person.Bird bird=P.new Bird();
调用外部类的非静态属性Person.this.name;
作为一个类
(可以定义属性、方法、构造器等
使用final则不能被继承
可以使用abstract)
作为外部类的成员
(调用外部类的结构
可被static修饰
可使用四种权限修饰符)
局部内部类(方法体内、代码块内、构造器内)
33.异常
java.lang.Throwable
java.lang.Error
java.lang.Exception
编译时异常checked(需要try-catch处理)
IOException
FileNotFoundException
ClassNotFoundException
运行时异常unchecked(一般不使用try-catch处理)
NullPointerException
ArrayIndexOutBoundsException
ClassCastException
NumberFormatException
InputMismatchException
ArithmeticException
Error:
java虚拟机无法解决的严重问题,一般不编写针对性代码进行处理。比如:堆溢出,栈溢出。
Exception:
其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。比如:空指针访问、视图读取不存在的文件、网络连接中断、数组角标越界。
编译时异常、运行时异常(除数为0,数组角标越界)
异常处理:
抛:生成对应异常类的对象,并抛出,后面代码不执行
抓:
try-catch-finally
try{//可能出现异常的代码}catch(异常类型1 变量名1){//异常处理语句}catch(异常类型2 变量名2){//异常处理语句}
finally{//一定会执行的代码(即使catch语句有异常或有return语句)比如关闭连接、关闭流}
throws+异常类型
写在方法声明处,需要在上层调用方法时try-catch解决。
手动抛出异常对象:throw new 异常类型(“异常”)
自定义异常类:继承现有异常类,序列版本号
注意:
try-catch后面代码会执行,throws方法内出现异常后不执行
try-catch异常顺序需要子类在上
子类重写的方法抛出的异常类型不大于父类被重写的方法的异常类型(多态性)
如果父类无throws,子类也不能使用,只能使用try-catch
若调用几个方法递进执行,建议使用throws,调用时try-catch