提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
1.类与对象
1.1 面向过程(pop)与面向对象(oop)
面向过程(pop): 面向过程是以过程为中心的,每一步都是自己实现的。
面向对象(oop): 面向对象是以对象为中心的,通过指挥对象来实现。
1.2 类与对象
类: 类是对一类事务的具体描述,是一组行为和属性的集合,是抽象的。
对象: 对象是该类的一个具体表现形式,是实际存在的,也称为实例,是具体的。
关系: 类是对象的模板,对象是类的实体。
类的结构:
属性:指代事务的特征,在类中通过成员变量来体现。
行为:指代的是执行的操作,在类中通过成员方法体现的。
构造器
代码块
内部类
1.3 类与对象的定义与使用
①、类的定义格式:
[权限修饰符] class 类名{
属性;
行为;
}
// 例如,建立一个学生类Student
class Student{
}
② 、成员属性定义格式:[权限修饰符] 数据类型 成员变量名 = 值;
// 例如:在学生类中添加姓名、年龄属性
class Student{
String name;
int age;
}
③、对象的创建格式: 类名 对象名 = new 类型();
// 例如在主方法内创建一个学生对象
public class Demo01 {
public static void main(String[] args) {
// 创建对象: 类名 对象名 = new 类名();
Student student = new Student();
}
}
// 学生类
class Student{
String name;
int age;
}
④、成员属性的调用:
静态: 类名.属性名
非静态: 对象名.属性名
public class Demo01 {
public static void main(String[] args) {
// 创建对象: 类名 对象名 = new 类名();
Student student = new Student();
// 使用成员属性
student.name = "张三";
student.age = 10;
System.out.println("student.name = " + student.name); //student.name = 张三
System.out.println("student.age = " + student.age);//student.age = 10
}
}
class Student{
String name;
int age;
}
⑤、成员方法的调用:
静态: 类名.方法名(参数)
非静态: 对象名.方法名(参数)
public class Demo01 {
public static void main(String[] args) {
// 创建对象: 类名 对象名 = new 类名();
Student student = new Student();
// 方法的调用
student.method();
}
}
class Student{
public void method(){
System.out.println("方法");
}
}
⑥、匿名对象
我们也可以不定义对象的句柄,而直接调用这个对象的方法。这 样的对象叫做匿名对象。 如:new Person().shout();
使用情况 :如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。 我们经常将匿名对象作为实参传递给一个方法调用。
⑤、对象内存分析图:
1.4 方法
概述: 用来完成某一个特定的功能的代码块。
定义的格式
[权限修饰符] [static] 返回值类型 方法名(参数列表){
方法体;
return 返回值;
}
// 代码实例
public void method(){
System.out.println("方法");
}
注意事项:
a、方法是平级的,不可以嵌套使用。
c、方法被调用一次,才会被执行一次。
d、方法的返回的结果是返回给调用者,结果由调用这进行处理。
e、没有返回值的方法,返回值类型是void,可以不写return语句,但系统会默认添加一个return。
方法的重载:
概述:在同一个类中,允许出现一个或一个以上方法名相同的方法,他们的参数列表(参数的个数\参数类型)不同,称为方法的重载。
注意事项:方法的重载与返回值类型无关。
public class Demo01 {
public static void main(String[] args) {
Sum sum = new Sum();
sum.getSum(1,2);
sum.getSum(1,2,3);
sum.getSum(1.0,2.0);
sum.getSum(1.0,2.0,3.0);
}
}
/**
* 定义一个方法,对不同的数据类型,不同参数个数 求和
*/
class Sum{
public void getSum(int a , int b){
System.out.println("int : a + b = " + ( a + b ));
}
public void getSum(int a , int b ,int c){
System.out.println("int : a + b + c = " + (a + b + c));
}
public void getSum(double a , double b){
System.out.println("double : a + b = " + ( a + b ));
}
public void getSum(double a , double b ,double c){
System.out.println("double : a + b + c = " + (a + b + c));
}
}
可变参数:
/**
* 概述:JavaSE1.5版本定义了一个Varargs机制,允许直接定 义能和多个实参相匹配的形参。
* 从而,可以用一种更简单的方式,来传递个数可变的实参。
* 格式:方法名(数据类型 ... 变量名){}
* 注意事项:
* 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
* 可变个数形参的方法与同名的方法之间,彼此构成重载
* 可变参数方法的使用与方法参数部分使用数组是一致的
* 方法的参数部分有可变形参,需要放在形参声明的最后
* 在一个方法的形参位置,最多只能声明一个可变个数形参
*/
public class Demo02 {
public static void main(String[] args) {
method(1,2,3,4,5,6);
}
public static void method(int...a){
for (int i : a) {
System.out.println(i);
}
}
}
参数传递机制: Java中参数传递的方式只有一种,值传递,就是将值复制给形参。
①、形参是基本数据类型:将实参基本数据类型变量的 数据值 传递给形参,其原内容不会发生变化。
②、形参是引用数据类型:将实参引用数据类型变量的 地址值 传递给形参,其原内容会发生变化。
递归: 方法自己调用自己的过程。
/**
* 递归
* 求1-100的阶乘
*/
public class Demo03 {
public static void main(String[] args) {
System.out.println("fac(5) = " + fac(5));
}
public static int fac(int num){
// 递归出口
if (num == 1){
return 1;
}
// 递归规律
return fac(num - 1) * num;
}
}
1.5 构造方法(构造器)
构造器的特征:
a.方法名必须与类名保持一致。
b.构造器没有返回值
c.构造器没有返回值类型
执行时机:
实例化对象时,进行加载
构造器的作用:
创建一个对象,并初始化赋值操作
格式:
[权限修饰符] 类名(参数列表){
方法体;
}
注意事项:
a、每一个类都有一个构造器,没写系统会默认提供一个空参构造。
b、在类中,一旦定义了构造方法,则系统则不再提供构造。
c、在同一个类中,可以重载多个构造方法。
d、子类不能继承父类的构造方法。
public class Demo04 {
public static void main(String[] args) {
Student student = new Student();
Student student1 = new Student("张三");
}
}
class Student{
public Student(){
System.out.println("空参构造");
}
public Student(String name){
System.out.println("带参构造");
}
}
2.面向对象的三大特征
2.1 封装
封装概述: 隐藏对象内部的复杂性,提供一个简单的访问接口。便于外界调用,从而提高系统的可扩展性和可维护性。 简单的说,该暴露的暴露,该隐藏的隐藏,这就是封装的思想。
封装原则: 将类中的某些信息进行私有化(private),不让外部程序直接访问。而是提供一个公共的访问方法(getXxx、setXxx),对其进行访问。
封装的好处: 提高代码的可扩展性,可维护性,复用性
private关键字:
private 私有的,是一个权限修饰符,被他修饰的成员变量或方法,只能在本类中进行访问。
若想要被其他类访问,需要提供一个公共的访问方法getXxx()\setXxx().
/**
* 封装一个学生类,将姓名、年龄私有化提供一个公共的访问方法。
*/
public class Demo01 {
public static void main(String[] args) {
// 创建学生对象
Student student = new Student();
student.setName("张三");
student.setAge(11);
System.out.println("student.getName() = " + student.getName());
System.out.println("student.getAge() = " + student.getAge());
}
}
class Student{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
this关键字
指代的是当前对象的引用
作用:
1. 在任意方法或构造器内,如 果使用当前类的成员变量或成 员方法可以在其前面添加this, 增强程序的阅读性。不过,通 常我们都习惯省略this。
2. 当形参与成员变量同名时, 如果在方法内或构造器内需要 使用成员变量,必须添加this来 表明该变量是类的成员变量
3.使用this访问属性和方法时, 如果在本类中未找到,会从父 类中查找
注意:
可以在类的构造器中使用"this(形参列表)"的方式,调用本类中重载的其 他的构造器!
明确:构造器中不能通过"this(形参列表)"的方式调用自身构造器
如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了 "this(形参列表)" "this(形参列表)"必须声明在类的构造器的首行!
在类的一个构造器中,最多只能声明一个"this(形参列表)"
2.2 继承
概述: 当多个类中具有相同属性和方法时,可以将这些相同的属性和方法抽取到同一个类中,让这些类继承该类,这个过程称为继承。
格式: class 子类 extends 父类{}
public class Demo04 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.fu();
}
}
class Fu{
public void fu(){
System.out.println("父类方法");
}
}
class Zi extends Fu {
public void zi(){
System.out.println("子类方法");
}
}
继承作用(好处):
①、减少代码的冗余,提高代码的复用性。
②、继承的出现,有利与功能的扩展,提高了可扩展性。
③、让类与类之间产生联系,是多态的前提条件。
继承的弊端: 让类与类之间产生了联系,增加了代码的冗余
继承的特点:
a、Java只能支持单继承,不能支持多重继承。
b、Java支持多层继承。
c、子类继承父类,就继承父类的所有的属性和方法。
d、一个父类可以有多个子类
继承中成员变量访问特点: 采用的是就近原则
子类局部变量范围-》子类成员变量范围-》父类成员变量范围
方法重写:
/**
* 方法重写
* 概述:当子类与父类出现相同的方法声明时(参数列表也必须相同);
* 要求:
* a、方法名,参数列表必须相同。
* b、子类返回值类型必须小于或等于父类方法的返回值类型
* c、子类的权限修饰符必须大于等于符类的权限修饰符
* d、子类所抛出的异常不能大于父类的异常
*/
public class Demo05 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.method();
}
}
class Fu{
public void method(){
System.out.println("父类方法");
}
}
class Zi extends Fu {
public void method(){
System.out.println("子类重写父类方法");
}
}
方法的重写与方法的重载的区别:
参数列表:方法的重写参数列表必须相同,重载才参数列表必须不同
执行的范围:方法的重写时子类与父类,重载时在同一个类中表现的
返回值类型:方法重写子类的返回值类型可以不同,重载必须相同
super关键字
代表父类存储空间的标识(可以理解成父类的引用)
使用格式:
super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的
super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的
super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错
注意事项:
a、子类的所有构造器都会默认调用父类的空参构造
b、若父类没有空参构造,子类构造器中必须通过super(参数列表)\this(参数列表)来调用父类中相应的构造方法。
同时二者只能选其一,并且该语句要放在子类构造器中的第一行
c、若以上条件都没有,则编译器会编译错误
权限修饰符:
2.3 多态
概述: 同一个对象的不同表现形态,也就是父类指向子类对象
多态的前提条件:
a、类与类之间是继承关系
b、方法要重写
c、父类指向子类对象
成员访问特点:
成员变量:编译时看父类,运行时看父类。
成员方法:编译时看父类,运行时看子类。
多态的好处: 提高代码的通用性和扩展性。
多态的弊端: 不能使用子类的特有成员
多态的转型:
向上转型:当左边的变量的类型(子类) > 右边对象/变量的编译时类型(父类),也就是父类指向子类对象
向下转型:当左边的变量的类型(子类) < 右边对象/变量的编译时类型(父类)
格式:子类型 对象名 = (子类型)父类引用;
多态转型的风险:
如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现 ClassCastException
解决方案:instanceof关键字
变量名 instanceof 类型
通俗的理解:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果
2.4 其他关键字
static关键字:
是Java中的一个修饰符。
特点:
a、随着类的加载而加载
b、优于对象存在
c、可以通过类名调用
d、被static修饰的变量被该类的所有对象共享。
注意事项:
静态可以调用静态
静态可以调用非静态
非静态不可以调用静态
native关键字:
ative只能修饰方法,表示这个方法的方法体代码不是用Java语言实现的,而是由C/C++语言编写的。
但是对于Java程序员来说,可以当做Java的方法一样去正常调用它,或者子类重写它。
final关键字:
最终的,最后的。
final修饰类,该类不可以被继承。
final修饰方法,该方法不可以被重写。
final修饰变量,该变量为常量,赋值完成后,不可以再次赋值。
3.面向对象进阶
3.1 代码块
概述:对Java代码进行初始化操作,用{}括起来的操作。
分类:
静态代码块:用static 修饰的代码块
可以有输出语句。
可以对类的属性、类的声明进行初始化操作。
不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
若有多个静态的代码块,那么按照从上到下的顺序依次执行。
静态代码块的执行要先于非静态代码块。
静态代码块随着类的加载而加载,且只执行一次。
非静态代码块:没有static修饰的代码块
可以有输出语句。
可以对类的属性、类的声明进行初始化操作。
除了调用非静态的结构外,还可以调用静态的变量或方法。
若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
每次创建对象的时候,都会执行一次。且先于构造器执行。
3.2 抽象类
概述: 如果一个类中,有一个或多个方法没有具体的实现方式,那么可以将该方法定义为抽象方法,则该类为抽象类。
抽象类方法的定义:
抽象类:用abstract修饰的类为抽象类
抽象方法:用abstract修饰的方法称为抽象方法。
public class Demo01 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
}
}
abstract class Fu {
public abstract void show();
public void method(){
System.out.println("父类方法");
}
}
class Zi extends Fu{
@Override
public void show() {
System.out.println("子类重写父类的抽象方法");
}
}
抽象类的特点:
抽象类的特点:
a、抽象类和方法必须用abstract关键子修饰
格式:public abstract 类名{}
public abstract 返回值类型 方法名(参数列表);
b、抽象类不可以被实例化
c、抽象类中可以没有抽象方法,但有抽象方法的类一定是抽象类
d、若一个子类继承了抽象类:
普通类:则重写父类所有的抽象方法。
抽象类:可以不重写,也可以部分重写。
e、抽象类中可以有构造方法
3.3 接口(interface)
概述: 本质是契约,标准,规范,就像我们的法律一样。
接口的特点:
①、接口用关键字interface修饰
②、子类实现接口用implements实现
③、子类实现接口要么子类是抽象类,要么重写接口的所有抽象方法
④、接口中没有构造方法
⑤、接口采用多实现机制
接口的成员特点:
成员变量:public static final 进行修饰为常量
成员方法:public abstract 进行修饰
类与接口关系:
①类与类的关系 继承关系,只能单继承,但是可以多层继承
②类与接口的关系 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
③接口与接口的关系 继承关系,可以单继承,也可以多继承
public class Demo02 {
public static void main(String[] args) {
Student student = new Student();
student.eat();
student.see();
Teacher teacher =new Teacher();
teacher.eat();
teacher.see();
}
}
// 接口
interface Person{
public abstract void eat();
public abstract void see();
}
// 实现类
class Student implements Person{
@Override
public void eat() {
System.out.println("学生吃饭");
}
@Override
public void see() {
System.out.println("学生看书");
}
}
// 实现类
class Teacher implements Person{
@Override
public void eat() {
System.out.println("老师吃饭");
}
@Override
public void see() {
System.out.println("老师看教案");
}
}
3.4 内部类
概述: 在一个类中定义一个类。
内部类的访问特点:
①内部类可以直接访问外部类的成员,包括私
②外部类要访问内部类的成员,必须创建对象
成员内部类
位置:类中方法外
定义格式:
[权限修饰符] [static] class 外部类名{
[权限修饰符] class 内部类名{
}
}
访问方式:
非静态:外部类名.内部类名 对象名 = new 外部类名().内部类名();
静态::外部类名.内部类名 对象名 = new 外部类名.内部类名();
外部类名.内部类名.方法名();
注意事项:
a、非静态的成员内部类中的成员不能声明为static的,只有在外部类或static的成员内部类中才可声明static成员。
b、外部类访问成员内部类的成员需要实例化
c、内部类可以直接调用外部类的所有成员
d、当想要外部类的静态成员部分使用内部时,可以考虑内部类声明为静态的
局部内部类
位置:在方法中
定义格式:
[权限修饰符] 返回值类型 方法名(参数列表){
[final\abstract] class 类名{
}
}
字节码文件名称:外部类$编号局部内部类名
特点:
内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但 是前面冠以外部类的类名和$符号,以及数字编号。
只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方 都不能使用该类。
局部内部类可以使用外部类的成员,包括私有的。
局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局 部变量的声明周期不同所致。
局部内部类和局部变量地位类似,不能使用public,protected,缺省,private 局部内部类不能使用static修饰,因此也不能包含静态成员
匿名内部类:
概述:匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。
格式:
new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}
特点:
匿名内部类必须继承父类或实现接口
匿名内部类只能有一个对象
匿名内部类对象只能使用多态形式引用
3.5 枚举
定义的格式
【修饰符】 enum 枚举类名{
常量对象列表
}
【修饰符】 enum 枚举类名{
常量对象列表;
其他成员列表;
}
枚举的特点:
- 枚举类的构造,一定是privatede
- 枚举类的构造可以是空参构造,可以是有参构造
* 编译器给枚举类默认提供的是private的无参构造,
如果枚举类需要的是无参构造,就不需要声明,写常量对象列表时也不用加参数,
* 如果枚举类定义有参构造,直接在常量对象名后面加(实参列表)就可以
- 枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写
- 如果常量对象列表后面没有其他代码,那么“;”可以省略,否则不可以省略“;”
- 枚举类默认继承的是java.lang.Enum类,因此不能再继承其他的类型
- 枚举类重写了Object的toString方法,默认返回的是常量名
- JDK1.5之后switch,提供支持枚举类型,case后面可以写枚举常量名。
- 枚举类型如有其它属性,建议(不是必须)这些属性也声明为final的,因为常量对象 在逻辑意义上应该不可变。
枚举的常用方法:
1.String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
2.String name():返回的是常量名(对象名)
3.int ordinal():返回常量的顺序号,默认从0开始
4.枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
5.枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象