黑马程序员-面向对象编程基础

来源:互联网 发布:网络兼职打码员 编辑:程序博客网 时间:2024/06/06 08:48

------- android培训、java培训、期待与您交流! ----------

什么是面向对象?
回忆:把大象装进冰箱的例子;

面向对象的特征:封装,继承,多态。

类:对现实生活中事物的描述;例:生产汽车的图纸;

对象:就是描述的这类事物,具体存在的个体;例:通过图纸生产出来的实实在在的汽车;

描述事物归纳起来其实就是两个方面:描述事物的属性和描述事物的行为;

属性对应是类中变量,行为对应的类中的函数(方法)。
其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法)。
要点:成员变量作用于整个类中;是对象的基本组成部分,存在于堆内存中,类加载就有默认初始化值,可以参与运算。
局部变量作用于方法或者语句中,存放在栈内存中,不初始化无法参与运算。

知识点:匿名对象;用法 new 类名().类成员
例:new person().age=10;
new person().name=“zhagsan”;//两个语句操作的不是同一个对象;
相对于有名对象来说匿名对象每new一次就创建一个对象,并只用一次。
匿名对象使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。
如果对一个对象进行多个成员调用,必须给这个对象起个名字。
匿名对象使用方式二:可以将匿名对象作为实际参数进行传递。


封装:类就是封装特性的最基本体现;
具体来说其实封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
在我们使用对象时不需要知道对象里面是怎么工作的只需要知道这个对象的怎么使用的旧可以;
原则:将不需要对外提供的内容隐藏起来。
把属性都隐藏,提供给对外公供方法对其访问。
函数就是java中最小的封装体。

private:私有,权限修饰符:用于修饰类中的成员;是封装的一种表现形式。
被private修饰的成员是私有的只在本类中有效,外部无法访问即使在外部建立了对象也无法访问:
但是在实际应用中外部需要访问到类中被私有修饰的成员,那么这就需要在类中提供对应访问成员变量的方式;
例:person类中的name变量私有;
class
{
private String name;
public void setName(Sting name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
一个类中一个属性(成员变量)一般对应两个方法set设置和get获取;
之所以对外提供访问方式,是可以在访问方式中加入逻辑判断语句,对访问的语句进行判断等操作,提供代码的健壮性;
例:person(人)这个类有年龄属性,年龄属性按照实际情况有一定的范围(例1到14岁)为防止不合理输入,那么可以在set方法中定义判断输入语句。
private int age;
public void setAge(int a)
{
if(a>0 && a<140)
{
age = a;
speak();
}
else
System.out.println("非法的 age");
}

public int getAge()
{
return age;
}
要点:私有仅仅是封装的一种表现形式。私有是封装,封装并不是私有;

构造函数:
作用:是一种特殊的方法 用来在创建对象时初始化对象 即为对象成员变量赋初始值。
对象一建立就调用与之对应的构造函数;
特点:1,函数名与类名相同。
2 ,没有返回值类型;
3,没有return语句;
知识点:一个类中没有定义构造函数时,系统会默认自动给给该类加入一个空参数的构造函数,但是类中自定义了之后系统就不会自动添加了;
类里面的构造函数可以私有化,可以用来阻止类创建对象。
构造函数和一般函数的去在运行上的区别:
构造函数是在对象一建立就运行,给对象初始化,而一般方法要对象或者类名调用(静态的情况下)才执行。
一个对象建立,构造函数只运行一次而一般方法可以被该对象调用多次。

知识点:构造代码块
例:class person
{
{ 构造代码块}
person();
}
作用:给对象初始化,对象一建立就运行,而且优先于构造函数执行。
与构造函数的区别:
构造代码块给所有对象进行初始化,里面定义的是不同对象的共性的初始化内容;
构造函数给对应的对象初始化,定义的是不同对象的初始化内容;

关键字 this:
代表所在函数所属对象的引用。即:调用了包含this关键字的函数的对象就是this引用的对象。
this的应用:当类中定义函数时该函数内部要用到该函数的对象时,这时用this来标识这个对象。
但凡本类功能内部使用到了本类对象都用this表示。
要点:this代表本类对象的引用并不是一个对象。
拓展:构造函数间的调用只能用this关键字。因为始终构造的是一个对象;
例:class Person
{
private String name;
private int age;
Person(int age)
{
this.age = age;
}
Person(String name,int age)
{
this(age);//注意这里this没有点,并且必须是构造函数中第一个语句;
this.name = name;
}
}
为什么this语句要放在初始化动作第一行(第一个位置)?
因为初始化原则:初始化动作要先执行,如果初始化动作中包含更细节的初始化动作也要先执行;

关键字 static :静态
用法:1,是一个修饰符用于修饰成员(成员变量,成员函数),和静态代码块;
2,当成员被静态修饰后就多了一个调用方式,除了可以别对象调用外还可以会接被类名调用。
静态的特点:(在内存中)随着类的加载而加载,随着类的消失而消失
被所有对象所共享;
优先于对象存在;
可以直接被类名调用;

静态使用注意事项:
1,静态方法只能访问静态成员。非静态方法既可以访问静态也可以访问非静态。
2,静态方法中不可以定义this,super关键字。因为静态优先于对象存在。所以静态方法中不可以出现this。
3,主函数是静态的。

静态利弊:实际应用中定义静态参考依据;
利:对对象的共享数据进行单独空间的存储(方法区中),节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。
弊:生命周期过长。访问出现局限性。(静态方法只能访问静态成员。)

什么时候定义静态?
静态变量:当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。
静态函数:当函数内部没有访问到非静态数据(对象的特有数据),那么该函数可以定义成静态的。
静态的典型应用:工具类
知识点:静态代码块
格式:static {静态代码块执行语句}
特点:随着类的加载而执行,并且只执行一次,用于给类进行初始化,优先于主函数,使用类中的内容即加载类;
与构造代码块的区别:一个是给类进行初始化(静态代码块);优先于主函数;
一个是给对象进行初始化(构造代码块);优先于构造函数
要点:如果在静态代码块中加入System.exit(0);语句会直接结束程序。不会执行主函数。



对象的初始化过程:
例:person p=new person("zhangsan",40);







继承:
关键字:extends
继承定义: 继承是类与类之间的一种关系,是使用已存在的类的定义作为基础建立一个新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能。
格式:class 子类 extends 父类{};
例:已有一个person类 现在要建一个Student类
class person
{
String name;
int age;

}
class Student extends person
{
//学生也是人也具有人的所有属性
}

要点: 继承提高了代码的复用性,但是不能为了其他类的功能或者仅仅是为了简化代码的书写而继承,必须是类与类之间有所属的关系才 能继承。
java普通类只支持单继承和多层继承体系,不支持多继承;(接口与接口之间支持多继承)
为什么不支持多继承:因为多继承容易带来安全隐患,如果多个父类中定义了相同的方法但方法内容不相同不能够明确运行哪一个
方法。但是java保留的了多继承这种机制并,用多实现的方式体现。
如图:





如何使用一个多层继承体系中的功能?
想要使用体系,要先查阅体系中父类的描述,因为父类中定义的是该体系中的共性功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么在具体调用时,要创建最子类的对象,因为有可能父类不能创建对象,并且创建子类对象可以使用更多的功能,
包括基本的也包括子类特有的。
总结一句话:查阅父类功能,创建子类对象使用功能。

继承关系中成员变量的特点:
如果子类中出现非私有的成员变量时子类要访问本类中的变量用this;
如果子类要访问父类中的同名变量,用super。
知识点:super的使用和this的使用几乎一致。
this代表的是本类对象的引用。
super代表的是父类对象的引用。

继承关系中普通函数的特点:
当子类中出现和父类相同的函数时,对子类对象调用该函数时执行的是子类函数的内容;这是函数的覆写特性;
当子类继承父类沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,
这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。
要点:1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2,静态只能覆盖静态。(内存中先加载后加载的问题)
重载:只看同名函数的参数列表(不看返回值类型)。
重写:子父类方法要一模一样(包括返回值类型)。
继承关系中构造函数的特点:

在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();

为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

要点:super语句一定定义在子类构造函数的第一行。

例:
class Fu
{
Fu(){}
}
class Zi extends Fu
{
int x;
Zi()
{
ssuper();
}
Zi(int x)
{
this();
this.x=x;
}
}
总结:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式super();

要点:当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数(子类构造函数第一行要么this语句要么super语句二者只能取其一)。如果子类构造函数第一行中this语句,那么子类中至少会有一个构造函数会访问父类中的构造函数。

知识点:关键字 final (最终)
可以修饰类,函数,变量。
被final修饰的类不能被继承。为了避免被继承,被子类覆写功能。
被final修饰的方法不能被覆写。
被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,又可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。
而这个值不需要改变,所以加上final修饰。
作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。
单词间通过_连接。



多态:
通俗的理解为多种事物存在的多种体现形态;例:男人和女人都称之为人(父类),男人和女人人这个父类的子类对象;
多态的基本体现形式:父类的引用指向自己的子类对象。
父类的引用接收自己的子类对象
例:
abstract class person
{
public static final void eat()
{
System.out.println("吃饭");
}
public abstract void work()
{
}
}
class student extends person
{
public static void work()
{
System.out.println("学习");
}

}

class teacher extends person
{
public void work()
{
System.out.println("教书");
}
}

class Doteacher
{
public void DoSomeThing(person p)//父类的引用接受子类对象
{
p.work();
p.eat();
}
}
class Demo
{
public static void main(String[] args)
{
person p=new student();//父类的引用指向子类对象
p.work();
Doteacher dt=new Doteacher();
dt.DoSomeThing();
}
}

多态的前提
必须是类与类之间有关系。要么继承,要么实现。并且类与类中的方法存在覆盖。否则多态没有意义;
多态的利弊:多态提高了程序扩展性并且简化了代码,但是使用父类的引用无法只能访问父类中的成员,无法访问子类的特有成员,否则必须要对父类的引用进行强制转换。

多态应用时需注意:
在多态中非静态成员函数的特点:
在编译时期:参阅引用型变量所属的类中(父类)是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类(子类)中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边(父类引用),运行看右边(子类对象)。
多态中非静态成员函数的特点:
在多态中,静态成员函数的特点:父类引用看父类中同名静态成员函数。
在多态中,成员变量的特点:都参阅右边(子类对象);
无论编译和运行,都参考左边(引用型变量所属的类)

设计模式:
解决某一类问题的最行之有效的方法:
单例设计模式:解决一个类只需在内存中只存在一个对象的的问题;
如何保证对象唯一:
1,为了避免其他程序过多的建立对象,先禁止其他程序建立该对象; 方法:将构造函数私有化;
2,为了让其他程序可以访问本类对象,在本类中自定义一个对象。 方法:在本类中创建本类对象
3,为了方便其他程序对自定义对象的访问可以对外提供一些访问方式。方法:对外提供一个获取该对象的方法。
方式一:先初始化对象不管用不用。称之为饿汉式;
例:class Student
{
private Student(){}
private static Student stu=new Student();
public static Studet getStudent()
{
return stu;
}
}

方式二:对象被调用时才初始化,也叫对象的延时加载;称为:懒汉式;

例:class Student
{
private Student()
{ }
private static Student stu=null;
public static Student getstudent()
{
if(stu==null)
stu=new Student();
return stu;
}
}
延时加载:Student类加载的时候,对象还不存在,当调用getStudent()方法时才创建Student对象;
单例的应用:软件的配置文件,软件一运行就要有配置文件不能调用配置文件时再建立。
原则:一般建议用饿汉式,一定会先建立一个对象,如实际生活中软件配置文件的应用。

------- android培训、java培训、期待与您交流! ----------