一.面向对象概述
何谓面向对象:
所有的东西都是对象。
程序是一大堆对象的集合,他们通过消息传递,各个对象之间知道要做些什么。
每个对象都分配有自己的存储空间,可容纳其他对象。
每个对象都有一个类型。
同一类的所有对象能接收相同的消息
程序是一大堆对象的集合,他们通过消息传递,各个对象之间知道要做些什么。
每个对象都分配有自己的存储空间,可容纳其他对象。
每个对象都有一个类型。
同一类的所有对象能接收相同的消息
对象特征:
ehavior—说明这个对象能做什么。
State—当对象施加方法时对象的反映。
Identity---与其他相似行为对象的区分标志,每一个对象有唯一的indentity, 而这3者是相互影响的。
State—当对象施加方法时对象的反映。
Identity---与其他相似行为对象的区分标志,每一个对象有唯一的indentity, 而这3者是相互影响的。
最重要的思想就是类,类是模板是蓝图,从类中构造一个对象,即创建了一个类的实例,打个比方:类好比一个建材市场,其中许多子类--各种各样的装饰材 料,而我们自己装饰的房子就是自己选择需要的材料
类之间的关系: 依赖关系(use - a),聚合关系(has - a),继承关系(is - a)
OOP 设计最重要经验:谁拥有数据,谁就对外操作这些数据的方法
面试题:两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子。
木材做成椅子,木材是原材料,工厂设计
chair = ChairFactory.makeChar(wood);
木材是由石刀砍树得来了
wood = StoneKnife.cut(free)
石刀又是有两块石头磨成而来了,石头是原材料,工厂设计
stoneKnife = KnifeFactory.makeKnife(stone);
面向对象特征:
封装:
隐藏对象的属性和实现的细节,只提供公共访问的方式。比如电脑里面的配件普通人不需要知道里面是怎样连接的,只需要知道外面的接口怎样使用有什么功能即可!这样的好处就是提高了复用性,安全性,还可以将变化隔离在那一部分代码,方便使用
eg:
public void print(Object obj){
System.out.println(obj);
}
继承:
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只需要继承那个类即可
多态:
一个对象在程序不同运行时刻代表的多种状态,父类或接口的引用指向子类
成员变量与局部变量
作用域:成员变量用于整个类
局部变量用于方法和语句中
生命周期:成员变量随着类的创建,存在堆区,随着类的消失而消失
局部变量 随着方法调用或者语句执行而存放在栈内存,调用后或语句结束自动释放
初始值: 成员变量有默认值
局部变量必须赋值
eg:
class Test{
int a; // 成员变量
public void methA(){
int b = 0; // 局部变量
}
}
匿名对象: 没有名字的对象,调用一次,被gc自动释放回收
eg:
new Random().nextInt(100);
构造方法
特点: 方法名与类名相同,无返回值,无返回值类型
作用: 构造函数是用于创建对象并对其进行初始化赋值,对象一旦创建就会调用相应的构造函数
注意:没有定义构造方法,系统默认缺省的无参构造方法
eg:
public class Test{
Test(){ //无参构造
}
Test(int a,int b){ // 有参构造
}
}
构造函数没有覆盖。
构造函数没有继承过来,通过super访问父类构造函数。
在子类的构造函数中第一行有一个默认的隐式语句。super();
子类实例化过程,子类中所有的构造函数默认都会访问父类中的空参数的构造函数
eg:
class Fu
{
private int num = 4;
public void setNum(int num)
{
this.num =num;
}
public int getNum()
{
return this.num;
}
}
class Zi extends Fu
{
//int num = 5;
void show()
{
System.out.println(num);
}
}
class ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
//System.out.println(z.num+"...."+z.num);
}
}
对象在JVM初始化过程
/**一个对象实例化过程:
Person p = new Person();
1.jvm读取并解释的Person.class文件,进行解析,并加载进内存,进入到方法区,形成常量池与方法表
2.并会先加载Person的父类(如果有直接的父类的情况下).在堆内存中开辟空间,分配地址。
3.并在对象空间中,对对象中的属性进行默认初始化。
4.调用对应的构造函数进行初始化。
5.在构造函数中,第一行会先调用父类中的构造函数进行初始化。
6.父类初始化完毕后,再对子类的属性进行显示初始化。
7.在进行子类构造函数的特定初始化。
8.初始化完毕后,将地址值赋值给引用变量。
**/
class Fu{
int num = 4;
void show1(){
System.out.println("fu show run");
}
}
class Zi extends Fu{
int num = 5;
void show(){
System.out.println(num+"......"+super.num);
}
void show1(){
System.out.println("zi show run");
}
}
public class ExtendDemo2 {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
z.show1();
//z.show2();
}
}
内存图表现形式:

-------------------------------------------------------------------------------------------------------------------------
二.多态与继承特性
一个类方法重写,多个类继承关系方法覆写,体现多态性质
某一种事物存在的多种体现形态。
多态自始至终都是子类对象在做着变化。
多态的体现:
1.父类的引用指向子类的对象(子类对象类型提升,自动向上转型)
2.父类的引用页可以接受自己的子类对象,(向下转型,需要强制类型转换)
多态的前提:必须是类与类之间有关系,要么继承,要么实现。
多态的好处:
1.多态大大提高了程序的扩展性
2.通常还有一个问题在覆盖
多态自始至终都是子类对象在做着变化。
多态的体现:
1.父类的引用指向子类的对象(子类对象类型提升,自动向上转型)
2.父类的引用页可以接受自己的子类对象,(向下转型,需要强制类型转换)
多态的前提:必须是类与类之间有关系,要么继承,要么实现。
多态的好处:
1.多态大大提高了程序的扩展性
2.通常还有一个问题在覆盖
eg:多态判断
class Animal
{
}
class Cat extends Animal
{
}
class Test
{
Animal animal = new Cat();//子类对象类型提升,自动向上转型
Cat cat = (Cat)animal;//父类引用转换为子类类型,向下转型需要强制类型转换
}
eg:多态体现
abstract class Animal{
abstract void eat();
}
class Dog extends Animal{
void eat(){
System.out.println("啃骨头");
}
void lookHome(){
System.out.println("看家");
}
}
class Cat extends Animal{
void eat(){
System.out.println("吃鱼");
}
void catchMouse(){
System.out.println("抓老鼠");
}
}
public class DuoTaiDemo {
public static void main(String[] args){
Animal a = new Cat();对象共性,都是动物
method(a);
method(new Dog());
}
public static void method(Animal a){
a.eat();
}
}
java保留了这种机制用另一种体现形式来完成表示多实现。
java支持多层继承,通过接口实现,也就是继承体系。
父类与子类中变量关系
子类继承父类后会拥有父类的成员,只不过有些成员不可见。
加载顺序:先加载父类成员后加载子类成员。
子父类中的变量:
如果子类中出现非私有的同名成员变量时,子类要访问本来变量用this,访问父类中的同名变量用super。
父类与子类中函数
当子类中出现和父类一模一样的函数(参数列表,返回值)时,当子类对象调用该函数,会运行子类函数的内容,如同父类被覆盖一样。这种情况是函数的另一种特性,重写(覆盖)。
覆盖:
1.子类覆盖父类,必须保证子类方法权限大于等于父类方法权限,才可以覆盖,否则编译失 败。
2.静态只能覆盖静态。因为静态优先于对象存在。
3.如果子类方法与父类私有方法同名,无法重写但不会报错,是一个新方法。
重载
当一个类中出现方法名相同,参数列表不同的方法时,被称为重载。重载可以改变返回值,因为它只看参数列表和名称。
当子类中出现和父类一模一样的函数(参数列表,返回值)时,当子类对象调用该函数,会运行子类函数的内容,如同父类被覆盖一样。这种情况是函数的另一种特性,重写(覆盖)。
覆盖:
1.子类覆盖父类,必须保证子类方法权限大于等于父类方法权限,才可以覆盖,否则编译失 败。
2.静态只能覆盖静态。因为静态优先于对象存在。
3.如果子类方法与父类私有方法同名,无法重写但不会报错,是一个新方法。
重载
当一个类中出现方法名相同,参数列表不同的方法时,被称为重载。重载可以改变返回值,因为它只看参数列表和名称。
-------------------------------------------------------------------------------------------------------------------------
三.封装特性
隐藏实现细节,并对外提供公共的访问方式。
函数或者类都是一个封装体。
特点:
1,隔离的变量。
2,便于使用。
3,提高复用。
函数或者类都是一个封装体。
特点:
1,隔离的变量。
2,便于使用。
3,提高复用。
私有在源代码中的使用就是在本类中有效。
通常会将成员变量xxx私有化,并对外提供对应的setXxx getXxx方法对其进行访问。
其实目的就是成员变量访问进行控制。 让成员的访问具备可控性,提高了程序的健壮性。
私有仅仅是封装的体现形式之一而已
通常会将成员变量xxx私有化,并对外提供对应的setXxx getXxx方法对其进行访问。
其实目的就是成员变量访问进行控制。 让成员的访问具备可控性,提高了程序的健壮性。
私有仅仅是封装的体现形式之一而已
eg:
public class Test{
private int a,int b;
public int getA(){
return this.a;
}
public void setA(int a){
this.a = a;
}
}
-------------------------------------------------------------------------------------------------------------------------
四.关键字(this,super,static,final)
this:代表的是对象。哪个对象调用了this所在的函数,this就代表哪个对象。
用法体现
1,当成员变量和局部变量同名时,可以用this区别。
2,当构造函数中调用本类其他构造函数时,可以用this完成。 this(实际参数);
这种调用必须定义在构造函数的第一行。初始化动作先完成。
应用:只要在定义功能时,用到了本类对象,那么就使用this来表示。
用法体现
1,当成员变量和局部变量同名时,可以用this区别。
2,当构造函数中调用本类其他构造函数时,可以用this完成。 this(实际参数);
这种调用必须定义在构造函数的第一行。初始化动作先完成。
应用:只要在定义功能时,用到了本类对象,那么就使用this来表示。
static关键字:
特点:
1,修饰成员。,
2,随着类加载,随着类消失。
3,优先于对象。
4,用类名直接访问
使用注意事项:
1,静态方法只能访问静态,静态有访问局限性。
2,静态方法中不能有this super关键字。
3,主函数是静态的
特点:
1,修饰成员。,
2,随着类加载,随着类消失。
3,优先于对象。
4,用类名直接访问
使用注意事项:
1,静态方法只能访问静态,静态有访问局限性。
2,静态方法中不能有this super关键字。
3,主函数是静态的
什么时候使用静态?
1,当成员变量的数据各个对象都相同时,可以用static修饰,让多个对象共享。
2,函数如果访问了特有数据(非静态成员变量),该函数是非静态的。
函数如果没有访问特有数据,那么该函数就可以静态修饰
1,当成员变量的数据各个对象都相同时,可以用static修饰,让多个对象共享。
2,函数如果访问了特有数据(非静态成员变量),该函数是非静态的。
函数如果没有访问特有数据,那么该函数就可以静态修饰
final 关键字
/*
final : 最终。作为一个修饰符,
1,可以修饰类,函数,变量。
2,被final修饰的类不可以被继承。为了避免被继承,被子类复写功能。
3,被final修饰的方法不可以被复写。
4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。
而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。
单词间通过_连接。
5,内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。
*/
class Demo
{
final int x = 3;
public static final double PI = 3.14;
final void show1()
{}
void show2()
{
final int y = 4;
System.out.println(3.14);
}
}
class SubDemo extends Demo
{
//void show1(){}
}
class FinalDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
代码块:
1,局部代码快。
对局部变量的生命周期进行控制。
对局部变量的生命周期进行控制。
eg:
public void load(){
{
int i = 0,y =0;
}
}
2,构造代码块。
对所有对象进行初始化。
eg:
public class Test{
{
}
public void methodA(){
}
public void methodB(){
}
}
3,静态代码块。
对类进行初始化
/*
静态代码块。
格式:
static
{
静态代码块中的执行语句。
}
特点:随着类的加载而执行,只执行一次,并优先于主函数。
用于给类进行初始化的。
*/
class StaticCode
{
int num = 9;
StaticCode()
{
System.out.println("b");
}
static
{
System.out.println("a");
}
{
System.out.println("c"+this.num);
}
StaticCode(int x)
{
System.out.println("d");
}
public static void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
static
{
//System.out.println("b");
}
public static void main(String[] args)
{
new StaticCode(4);//a c d
//new StaticCode();
//new StaticCode();
//System.out.println("over");
//StaticCode.show();
//StaticCode s = null;
//s = new StaticCode();
//StaticCode.show();
}
static
{
///System.out.println("c");
}
}