一、面向对象的程序设计
1.面向对象的设计其实是类的设计
2.设计类其实是设计类的成员
3.类的成员:成员变量&成员方法
扩展:类的成员共有五个:成员变量、成员方法、构造器、代码块、内部类
二、面向对象的落地法则
1.设计类并设计类的成员
2.通过类来创建对象,注意是用new关键字
3.通过对象名.变量,对象名.方法的形式来完成对象的使用,例如:a1.name;a1.info()
4.使用类创建了对象,该对象就拿到了该类所设计的一个“副本” 对其中一个对象的属性赋值,不会影响其他对象的该属性的值。
三、类的成员之属性
属性:就是类中的成员变量
成员变量VS局部变量
共同点:1.都是变量,他们的定义形式相同:类型 变量名 = 初始化值;
2.都有作用域:作用域是在一对大括号内
不同点:1.内存中存放的位置不同:
成员变量存放在堆空间内
局部变量存放在栈空间内
2.声明的位置不同(作用域不同):
成员变量声明在类的内部,方法的外部;
局部变量声明在方法的内部。
3.初始化值不同
成员变量可以不赋初值,其默认值按照其数据类型来定
局部变量必须显式地赋初值
4.权限修饰符不同
成员变量的权限修饰符有四个:public (default) protected private
局部变量没有权限修饰符,其访问权限依据其所在的方法而定(与方法的访问权限相同)
四、类的成员之方法
1.实例:
void setName(String n){
name = n;
}
String getName(){
return name;
}
void eat(){
//System.out.println("动物进食");
}
2.格式:修饰符 返回值类型 方法名(形参列表){方法体}
返回值类型:若方法有返回值,则返回值类型是该返回的值的数据类型;若没有则是void
形参列表:调用方法时实参传递给形参的“值”,当传递的是基本数据类型时,该“值”是具体的数值;当传递的是引用数据类型时,该“值”是引用数据类型变量的首地址值。
3.注意:方法内可以调用其他方法,但是方法内不能定义新的方法
五、对象的生命周期
1.对象一旦被创建,其生命周期就开始了
2.对象生命周期的结束:一旦对象所在的堆空间的区域没有被任何变量所引用,则意味着对象的生命周期结束了。
六、类的第三个成员:构造器(构造方法) Constructor
1.构造器的作用:
1)创建对象 “new 构造器”==》开辟了空间,创建了对象
2)给创建的对象的属性赋值等一些列初始化操作。
2.构造器的声明的格式:权限修饰符 类名(形参列表){},注意:构造器没有返回值类型,也就是没有返回值
3.如果类中没有显式地声明一个构造器,则系统会默认提供一个空参的构造器; 如果类中显式地声明了一个构造器(无论是否是空参),则系统不再提供空参的构造器。
4.一个类中可以有多个构造器。多个构造器之间构成了构造器的重载。
七、面向对象的特征一:封装
1.出现的场景:当我们直接通过对象.属性的方式给对象的属性赋值时,有可能会出现不满足实际情况(自然规律或特定条件)的意外。那么我们考虑将赋值的操作不通过直接给属性赋值来完成,而是通过方法来完成,将条件体现在方法里,以达到满足实际情况的要求。
2.解决不能直接作用于属性的办法:封装——通过private关键字来实现
private关键字:被private关键字修饰的属性和方法,表示该属性和方法只能在本类中被访问。出了本类就无法访问。
注意:在实际使用中,往往将属性私有化,再提供公共的方法访问这些私有化的属性。
八、this关键字
1.可以用来修饰属性、方法、构造器
2.this理解为当前的对象(或当前正在创建的对象)比如this.name,this.eat(),表示当前对象的name,当前对象的eat()
3.this可以用来调用构造器,通过“this(形参列表)”显式地调用本类中其他的构造器。
注意:
1)在构造器中通过this来调用其他构造器,则该this必须声明在首行;
2)如果一个类中有n个构造器,则最多只能有n-1个this()构造器调用语句。
九、再讲方法的参数传递
Java里方法的参数传递方式只有一种:值传递。
即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响,如果参数本身是地址值,则该地址值所指向的空间的内容被影响。
十、static关键字:静态的,修饰属性、方法、代码块、内部类
一、static修饰属性(静态的属性也称为类变量):
1.由类创建的所有的对象都共用该属性
2.当其中一个对象对其属性进行更改,会导致其他对象的该属性的值的变化。
类变量vs实例变量:
实例变量:非static修饰的变量,每个实例(对象)各自拥有一套副本
访问实例变量得通过“对象.属性”的形式访问,而不能通过“类名.实例变量”的形式访问。
3.类变量随着类的加载而加载,加载到静态域里,而且在内存中独一份。
4.可以通过“类名.类变量”的方式直接访问,因为这种方式“类名.类变量”意味着先加载类,再访问类变量。
5.类变量的加载是早于实例变量的,因此也可以通过对象.类变量的形式来访问类变量
6.类变量存在于静态域中。
二、static修饰方式(静态的方法也称为类方法)
1.类方法是随着类的加载而加载,在内存中也是独一份
2.可以通过“类.类方法”的形式调用,也可以通过“对象.类方法”来调用,因为类方法的生命周期早于对象,类方法被回收晚于对象被回收。
3.类方法内不能使用实例变量(即非static修饰的成员变量)
4.类方法内只能出现类变量,同理类变量可以被非static修饰的方法调用。
5.类方法里能否出现this、super关键字?不能
三、static修饰代码块:静态代码块(随着类的加载而加载)
1.代码块:由大括号组成的一个单位,该单位内可以包含多条语句。
1)静态代码块:被static修饰的代码块
2)构造代码块:是声明在方法的外部,类的内部
3)普通代码块:声明在方法的内部
2.加载顺序:静态代码块>main>构造代码块>构造器>普通代码块
十一、面向对象的特征二:继承
1.为什么要设计继承?复用性、扩展性
2.实现继承的方式:
classA extends classB 我们成为classA是子类,classB是父类(基类、超类),子类和父类是一个相对的概念
3.子类继承父类以后,就可以获取父类中的内容:属性和方法,并调用父类的构造器
明确:子类能否获得父类中私有的属性,能!但是由于封装性的设计,子类不能直接方法该私有属性,而是通过公共的方法来访问。
4.子类继承父类以后,可以定义自己特有的结构,明确子类是父类的扩展而不是父类的子集。
5.java中的继承机制:单根继承,即一个子类只能继承一个父类,但是一个父类可以有多个子类。
6.子类对象实例化的过程:
子类继承父类,将会调用父类的构造器,调用顺序是级别最“老”的父类构造器优先调用,依次调用下来直到子类构造器为止。每一级父类的构造器初始化该父类自己的内容,而不能初始化其子类的内容。注意:父类自己的内容包括从父类的父类里继承来的内容。
十二、super关键字
表示父类的,用来修饰属性、方法、构造器
1.当子类和父类有同名的属性时,可以通过"super.属性"的方式调用父类中的同名属性,注意:只能调父类的,调不到“爷爷”类的,并且“super.super.属性”是无效的。
super.属性 vs this.属性
super.属性:调用父类的属性
this.属性:调用本类的属性
2.当子类重写了父类的方法以后,子类可以通过“super.方法”的方式调用父类中的同名方法。
3.super修饰构造器:格式:super(形参列表)***难点***
1)如果在子类中不声明任何构造器,则系统会默认给子类一个空参的构造器,并且该构造器内默认调用父类的空参的构造器。如果此时父类中没有空参构造器则报错。
2)如果子类显式的声明了构造器,该构造器内若没有"super(形参列表)“语句,则系统会默认调用父类的空参的构造器。如果此时父类中没有空参构造器则报错。注意:无论调用子类的哪个构造器,子类的构造器里都隐藏着一个"super()"即调用父类空参的构造器。
3)如果子类构造器中显式的使用“super(形参列表)”指明调用父类的哪个构造器,则父类的空参构造器不被调用。
4)super修饰构造器的语句必须声明在首行
5)super修饰的构造器super()和this修饰的构造器this()不能同时出现,因为他们都需要被声明在首行。
十三、方法的重写
出现的前提:有子类继承父类
出现的场景:当子类继承了父类的方法后发现父类的方法不适用于子类,则子类可以通过重写父类的方法。
在调用时,调用的是子类重写后的方法,而不是来自于父类的方法。
重写的规则:
1)要求子类与父类的方法:返回值类型、方法名、形参列表必须完全相同。
2)子类的修饰符权限不能小于父类的修饰符权限
3)若父类方法抛异常,那么子类方法抛的异常类型不能大于父类方法抛的异常类型
4)子类可以重写父类的静态方法,但是必须是同为静态的
十四、访问权限修饰符
1.private:私有的,只能在本类中使用。
2.default: 默认的,只能访问本类或同一个包内的成员。不能访问其他包内的成员,也无法通过继承来访问default成员
3.protected:受保护的,如果一个类想要访问另一个类的protected成员,那么该类必须和对方类在同一个包下,或者是其子类。所以说若想要访问protected成员就得通过继承成为其子类。
4.public:公共的,所有人都能访问
注意:defalut、public可以用来修饰类,private protected不能修饰类。
十五、package和import
package 包名;指明类所属的包,使用”javac -d . 类名.java“编译生成带包路径的字节码文件
import 包名.类名(.*); 告诉编译器去哪里找类。注意:java.lang包下的类无须导包。
十六、Object类是所有类(自己创建的和java提供的)的根类
1.==
1)如果是基本数据类型,比较的是值是否相等
2)如果是引用数据类型,比较的是地址值是否相等
2.equals()
1)equals不适用于基本数据类型,equals只适用于引用数据类型
2)如果不重写equals方法,则比较的是两个对象的地址值,等效于“==”
3)像String、File、Date等类重写了Object的equals方法,比较的是两个String对象的具体的值,而不是地址值。
3.toString():
1)当我们打印一个引用数据类型的对象时,默认调用的是这个对象的toString();
2)当我们重写了toString()后再打印该对象,会调用重写后的toString();
3)像String、File、Date等类已经重写了toString方法。
十七、面向对象的特征三:多态
1.多态指的是什么?理解成一种事物的多种表现形态
2.以下几种情况会体现出多态性
1)方法的重载
2)方法的重写
3)子类对象的多态性
前提:1)要有类的继承 2)要有方法的重写
4)接口的引用
3.子类对象的多态性的体现:
虚拟方法的调用:通过父类的引用指向子类对象的实体,当调用方法时,实际执行的是子类的方法(即重写的父类的方法)
4.对于多态性来说,运行一个程序分为编译状态和运行状态。
编译状态:是判断“=”的左边是否满足要求。
运行状态:看的是“=”的右边,即真正要执行的子类对象的实体。
5.向上转型、向下转型:
Person p4 = new Man();
向下转型: 注意要使用"()"强制类型转换符
Man m1 = (Man)p4;
注意:向下转型容易出现要转的类型和实际的类型不符的错误,为了避免这种错误,我们在实际编程中往往这样做向下转型
if(p4 instanceof Man){
Man m2 = (Man)p4;
m2.getSomeFun();
}else if(p4 instanceof Woman){
Woman w2 = (Woman)p4;
w2.getSomeFun();
}
十八、抽象:abstract
1.abstract关键字可以用来修饰类、方法。
2.抽象方法:用abstract修饰的方法
声明的格式: 权限修饰符 abstract 返回值类型 方法名(形参列表);
注意:没有“{}”,且必须有“;”
3.抽象类:用abstract修饰的类
1)抽象类不能被实例化
2)抽象类有构造器
3)抽象类里可以有也可以没有抽象方法,但是有抽象方法的类必须用abstract修饰,表示是抽象类
4)子类继承抽象类,则必须重写父类中所有的抽象方法后才能被实例化,否则该子类也得声明为抽象的,成为抽象类.
4.abstract不能与以下关键字搭配使用:属性、构造器、private、final、static
属性:属性不能被重写。
构造器:构造器不能被重写。
private:子类无法直接访问父类的私有方法。
final:表示最终的,表示final修饰的内容不再发生改变,而abstract是希望被重写,所以冲突的
static:静态的:抽象类不能被实例化,而用static修饰的成员会随着类的加载而加载。
十九、final关键字:最终的,可以用来修饰类、属性、方法
1.final修饰类:这个类不能被继承
2.final修饰方法:这个方法不能被重写,当一个方法所要体现的功能已经被确定,则用final修饰。
3.final修饰属性:表示常量,则该常量必须有初始化值。
给常亮赋值的方式:
1)直接赋值:final int MY_INT=10;
2)在构造器中为常量赋值,因为构造器的作用是初始化
3)在构造代码块中为常量赋值,因为构造代码块的加载早于构造器
全局常量:用static final修饰的常量,因为用static修饰,表示随着类的加载而加载,因此成为全局常量
二十、接口:是与类并行的一个概念
1.接口是一个特殊的抽象类,它是常量与抽象方法的集合,即接口里只有常量和抽象方法,而不能有变量和普通方法。
接口里定义的常量已经默认被“public static final”修饰接口里定义的方法已经默认被“public abstract”修饰。
2.接口里有没有构造器?没有,因此接口不能被继承。
3.接口定义的是一种功能,因此,通过类来实现的方式,实现接口即实现功能。
关键字implements:实现:class SubClass implements InterfaceA{ }
4.若一个类实现了一个接口,就要重写接口里的所有抽象方法,才能被实例化,否则该类内仍有抽象方法,就意味着是抽象类,不能被实例化
5.java只支持单根继承,即一个子类只能有一个父类。——这是一种弊端。接口可以多实现,即一个类可以实现多个接口,这种优势打破了java中单根继承的局限
6.接口可以继承接口,并可以多继承,即一个接口可以继承多个接口,这种优势打破了java中单根继承的局限。
7.接口的多态性的体现:只要是实现了某一接口的类的对象,都能被该接口所引用。instanceof也适用于接口。
二十一、类的第五大成员:内部类
1.内部类就是在类的内部定义的类,也就是说外部的类叫外部类,内部的类叫内部类
2.内部类分为成员内部类和局部内部类
1)成员内部类:定义在类的内部,方法的外部,
A.特点:a.作为类的一个成员,有4个权限修饰符:public (default) protected private
b.作为一个类,可以用abstract、final修饰,也有构造器,也可以在类里定义属性、方法
B.成员内部类的注意事项:
a.非静态成员内部类:
1)创建对象的方式:先有外部类的对象,再通过外部类对象调用内部类的构造器,格式:外部类对象.new 内部类()
2)调内部类的属性,可以用"this."来指明;
调外部类的不同名属性,直接调用即可;
调外部类的同名属性:外部类的类名.this.同名属性:表示外部类的当前对象的属性
3)不能有静态的属性和方法
b.静态成员内部类:
1)创建对象的方式:调用构造器的方式:外部类类名.内部类()
2)可以有非静态的属性和方法
3)静态内部类只能调用外部类的静态属性、方法,不能调用外部类的非静态属性、方法
C.成员内部类的优势:成员内部类作为外部类的成员,可以直接访问外部类的私有属性。
2)局部内部类:定义在方法的内部,对于局部内部类我们常常使用一个方法,得到一个接口实现类的对象。局部内部类的优势:通过方法非常方便的得到一个接口实现类的对象。
注意:匿名内部类通过使用"new 接口(){}"的方式用其隐含实现一个接口或抽象类,实现的部分写在大括号内。
标签:对象,子类,知识,构造,修饰,父类,方法,面对,属性 From: https://www.cnblogs.com/longhj/p/17922263.html