1.什么是面向对象
java是一门纯面向对象的语言,在面向对象的语言中,最核心的内容就是对象,一切围绕着对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事。
2.类的定义和使用
2.1类是用来对一个对象进行描述的,主要描述对象具有那些属性,哪些功能,描述完成后计算机就可以识别了。类是组成java程序的基本要素,一个java程序是由若干个类所构成的,这些类既可以在一个源文件中,也可以分布在不同源文件中。
2.2类的定义格式
class 类名{
类体的内容
}
以下是两个类的声明的例子
class people{
...
}
class 动物{
...
}
class people class 动物被称为类的声明 people,动物 分别是类名,两个大括号以及中间的内容是类体。类的名字符合标识符的规定即由字母,数字,下划线或美元符号组成,,并且第一个字符不能是数字。类名采用大驼峰定义。
举例,我们定义一个洗衣机类;
class Washmachine {
//变量的定义
public String brand;
public String type;
public double weight;
public double length;
public double high;
public String color;
//方法的定义
public void washCloths() {
System.out.println("洗衣服");
}
public void dryClothes(){
System.out.println("甩干");
}
}
定义一个狗类
class Dog{
//变量声明部分
public String name;
public String color;
public String six;
//方法定义
public void barks(){
System.out.println(name+"汪汪汪");
}
public void wag(){
System.out.println(name+"摇尾巴");
}
定义一个学生类
class student{
//声明变量部分
public String name;
public String six;
public int age;
//方法定义
public void doHomeWork(){
System.out.println("做作业");
}
public void doClass(){
System.out.println("上课");
}
}
3.类的实例化
3.1什么是实例化
定义了一个类,就相当于在计算机中定义了一种新的类型,与内置类型相似,只不过类是用户自定义的新的类型。比如上述的dog,student类。有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。
public static void main(String[] args){
Dog a1=new Dog();
a1.name="san";
a1.color="greeen";
a1.six="bb";
a1.wag();
a1.barks();
Dog a2=new Dog();
a2.name="dfhsjd";
a2.color="add";
a2.six="sa";
a2.barks();
a2.wag();
}
注意:new关键字用于创建一个对象的实例. 使用.来访问对象中的属性和方法.
同一个类可以创建多个实例.
类和对象的说明
1.类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员。
2.类是一种自定义的类型,可以用来定义变量。
3.一个类可以实例化出多个对象,实例化出的对象,占用实际的物理空间,存储类成员变量。
4.this引用
举一个日期类的例子
public class text2{
public int year;
public int month;
public int day;
public void setday(int y,int m,int d){
year=y;
month=m;
day=d;
}
public void printData(){
System.out.println(year+"/"+month+"/"+day);
}
public static void main(String[] args){
text2 day1=new text2();
text2 day2=new text2();
text2 day3=new text2();
day1.setday(1999,2,21);
day2.setday(2001,12,22);
day3.setday(2311,11,22);
day1.printData();
day2.printData();
day3.printData();
}
}
上面定义了一个text2类,并且实例化了3个对象,并且进行了赋值和初始化。没有任何问题。但当我们构造setday这个方法时,我们将参数命名为与成员变量相同的名字时,又会发生什么呢?
public class text2{
public int year;
public int month;
public int day;
public void setday(int year,int month,int day){
year=year;
month=month;
day=day;
}
public void printData(){
System.out.println(year+"/"+month+"/"+day);
}
public static void main(String[] args){
text2 day1=new text2();
text2 day2=new text2();
text2 day3=new text2();
day1.setday(1999,2,21);
day2.setday(2001,12,22);
day3.setday(2311,11,22);
day1.printData();
day2.printData();
day3.printData();
}
}
上述代码不会再打印输入的日子,而打印的是默认值0
4.1this引用
为了解决上述问题,需要用到this引用
this引用指向当前对象(成员变量运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。
public class text2{
public int year;
public int month;
public int day;
public void setday(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public void printData(){
System.out.println(year+"/"+month+"/"+day);
}
public static void main(String[] args){
text2 day1=new text2();
text2 day2=new text2();
text2 day3=new text2();
day1.setday(1999,2,21);
day2.setday(2001,12,22);
day3.setday(2311,11,22);
day1.printData();
day2.printData();
day3.printData();
}
}
通过this引用,打印了输入的日期。
4.2 this引用的特性
1.this的类型:对应类型引用,即那个对象调用就是那个对象的引用类型。
2.this只能在成员方法中使用。
3.在“成员方法“中:this只能引用当前对象,不能再引用其他对象。
4.this是”成员变量”的第一个隐藏参数,编译器会自动传递,在执行成员方法时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接受。
public void setday(text2 this,int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
5.对象的构造及初始化。
在java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。局部变量要初始化才能使用,但为什么字段声明之后没有给值依然可以使用。
5.1构造方法
构造方法是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只执行一次。还是熟悉的例子
public class text1 {
//Data data1=new Data();
public static void main(String[] arsg){
Data data1=new Data();
Data data2=new Data(2101,12,12);
}
}
class Data{
public int year;
public int month;
public int day;
//构造方法
//名字与类名相同,没有返回值,一般情况下用public修饰,并且在对象的整个对象的生命周期内只调用一次
public Data(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
System.out.println("构造方法被调用");
}
public void print(){
System.out.println(this.year+"."+"\\"+this.month+"\\"+this.day);
}
}
上述例子中,实例化data1时没有传递参数,会导致错误。传递参数实例化data2成功运行。构造方法的作用是给对象中的成员进行初始化,并不负责给对象开辟空间。
5.2 构造器的特征
1.名字必须与类名相同。
2.没有返回值,设置为void也不行。
3.实例化对象时被调用,并且在对象的生命周期内只调用一次。
4.构造方法可以重载。
public class text1 {
//Data data1=new Data();
public static void main(String[] arsg){
Data data1=new Data();
Data data2=new Data(2101,12,12);
}
}
class Data{
public int year;
public int month;
public int day;
//构造方法
//名字与类名相同,没有返回值,一般情况下用public修饰,并且在对象的整个对象的生命周期内只调用一次
//构造方法的重载
public Data(){
this.year=1211;
this.month=12;
this.day=22;
System.out.println("不带参数的构造方法被执行");
}
public Data(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
System.out.println("构造方法被调用");
}
public void print(){
System.out.println(this.year+"."+"\\"+this.month+"\\"+this.day);
}
}
上述构造方法中,方法名相同,但参数列表不同,因此构成了方法的重载。
5.用户如果没有定义,编译器会默认生成一份不带参数的构造器。
public class text1 {
//Data data1=new Data();
public static void main(String[] arsg){
People a1=new People();
a1.print();
}
}
class People {
public String name;
public String sex;
public int age;
public void print() {
System.out.println(this.name+" "+this.sex+" "+this.age);
}
}
上述代码会成功运行并且输出null null 0 可见编译器默认的构造器会给相应的成员变量赋相应的零值。
如果用户定义了构造器,那么编译器就不再会生成不带参数的构造器。
public class text1 {
//Data data1=new Data();
public static void main(String[] arsg){
Data data1=new Data();
Data data2=new Data(2101,12,12);
}
}
class Data{
public int year;
public int month;
public int day;
//构造方法
//名字与类名相同,没有返回值,一般情况下用public修饰,并且在对象的整个对象的生命周期内只调用一次
public Data(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
System.out.println("构造方法被调用");
}
public void print(){
System.out.println(this.year+"."+"\\"+this.month+"\\"+this.day);
}
}
上述代码会报错,原因是已经书写了带参数的构造器,编译器不在提供默认的构造器,则会报错。
6.构造器中,可以通过this调用其他构造方法来简化代码。
public class text1 {
//Data data1=new Data();
public static void main(String[] arsg){
People a1=new People("zhangsan","男",19);
People a2=new People();
}
}
class People {
public String name;
public String sex;
public int age;
public People(){
this("lisi","女",11);
System.out.println("执行了不带参数的构造器");
}
public People(String name,String sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
System.out.println("执行了带参数的构造器");
}
}
上述程序会输出
可见通过this引用在实例化a2时,执行了带参数的构造方法。
public class text1 {
//Data data1=new Data();
public static void main(String[] arsg){
People a1=new People("zhangsan","男",19);
a1.print();
People a2=new People();
a2.print();
}
}
class People {
public String name;
public String sex;
public int age;
public People(){
this.name="lis";
this.sex="nan";
this.age=19;
System.out.println("执行了不带参数的构造器");
}
public People(String name,String sex,int age){
this();
System.out.println("执行了带参数的构造器");
}
public void print(){
System.out.println(this.name+" "+this.sex+" "+this.age);
}
}
可见通过this()可以在带参数的构造器和不带参数的构造器中相互调用,但不能成环,即不能互相调用。this()必须是构造器中的第一条语句。
5.3默认初始化
为什么局部变量在使用时必须要初始化,而成员变量在使用时就可以不用呢?
public class text1{
public static void main(String[] args){
People a1=new People();
}
}
class People{
public String name;
public String sex;
public int age;
}
上述的成员变量均为初始化,但可以正常编译。
People a1=new People();
这条语句在执行时,在JVM层面需要做很多事情
1.检测用于实例化对象的类是否加载了,如果没有加载则加载。
2.为对象分配内存空间。
3.处理并发安全问题
4.初始化所分配的空间
对象空间被申请好之后,对象中包含的成员已经设置好了初始值。
5.设置对象头信息。
所以实例化对象时,不对成员进行初始化也可以编译通过。
5.4就地初始化
声明成员变量时,就直接给出了初始值。
public class text1{
public static void main(String[] args){
People a1=new People();
a1.pirnt();
}
}
class People{
public String name="lisi";
public String sex="男";
public int age=21;
public void pirnt(){
System.out.println(name+" "+sex+" "+age);
}
}
输出如下
6.封装
6.1何为封装
面向对象程序有三大特性:封装,继承,多态。封装就是:将数据和操作数据的方法进行有机结合。隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
6.2访问限定符
java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对数据的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中有四种访问限定符:四种限定符的范围如下
private: 同一包中的同一类 默认(default):同一包中的同一类+同一包中的不同类
protected:同一包中的同一类+同一包中的不同类+不同包中的子类
public:同一包中的同一类+同一包中的不同类+不同包中的子类+不同包中的非子类
public class text1{
public static void main(String[] args){
People a1=new People(19,"lisi","nv",3);
System.out.println(a1.age);
System.out.println(a1.name);
System.out.println(a1.sex);
System.out.println(a1.grade);
}
}
class People{
public int age;
protected String name;
String sex;
private int grade;
public People(int age,String name,String sex,int grade){
this.name=name;
this.age=age;
this.sex=sex;
this.grade=grade;
}
}
由于private访问限定符的作用(允许在同一个包中的同一个类中访问),上述代码会报错如下