java基础知识——面向对象

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

3.面向对象

3.1什么是面向对象?

面向对象简单说就是面向具体特定功能的实体,面向对象的思想强调的是对象(实体),而不像是面向过程中,去强调过程,C语言就是面向过程的语言,而C++、Java、c#是面向对象的语言。 

3.2面向对象的特点:

1,  面向对象的思想,符合人们的思考习惯。

2,  面向对象将复杂问题简单化。

3,  面向对象让面向过程中的执行者,变成了指挥者。 

3.3类与对象的关系

类的定义:

权限修饰符class类名{

       成员变量;

       成员函数;

       构造函数;

       ……   

}

权限修饰符:在Java中类的权限修饰符,只能使用public、默认权限,不能使用:protected、private。

类名:遵循一个规范,组成类名的单词首字母都要大写。如:class TestDemo。

类:在Java中,类就是封装体,对某些事物的属性和行为进行描述,并进行封装。

对象:就是类所描述的某些事物的实体。使用关键字new就可以创建对象。

对象的创建:

类名变量名(对象名)=new 类名();

如:
class Person{
	int age;
	String name;
 }
public class Demo{
	public static void main(String[ ]args){
	Person p=new Person();//这里就创建了一个Person类的对象。
 }	
}


总结:类就是对象的蓝图,而对象就是类的实体。

3.4什么是成员?

类中的属性行为,是组成类的内容,就是类的成员。

类中的成员包括:

成员变量:定义在类中的变量。(要注意成员变量和局部变量的区分)

成员函数:定义在类中的函数。

如:

class Person{
       int age;
       String name;
void speak(){
       System.out.println(name+":"+age);
  }
}
//age、name:就是成员变量。
//speak():就是成员函数。

 

3.5对象在内存中的体现

如:
class Person
{
	private int age;
	private String name;
	
}
public class Demo
{
	public static void main(String[]args){
		Person p=new Person();
	}
}


 

 3.6局部变量和成员变量的区别

1,作用域不同

局部变量:定义在函数、语句、参数、局部代码块中,只在所属区域有效。

成员变量:定义在类中,只要在类中都有效。

2,存储位置不同

局部变量:存储在内存中的栈内存。

成员变量:存储在内存中的堆内存的对象中。

3,生命周期不同

局部变量:随着作用域执行而存在,随着作用域的结束而释放。

成员变量:随着对象的创建而存在,随着对象的回收而释放。

4,初始化值不同

局部变量:没有默认初始化值。

成员变量:随着对内存中对象的创建,会进行默认初始化。  

3.7匿名对象

什么是匿名对象?

简单说就是没有名字的对象,是创建对象的简写形式。

什么时候使用匿名对象?

1,当对象只对成员进行一次调用的时候。

如:
class Person
{
	private int age;
	private String name;
	void show(){
		System.out.println(name+":"+age);
	}
	
}
public class Demo
{
	public static void main(String[]args){
		new Person().show();//使用匿名对象,调用一次show()方法。
	}
}



 

因为每次使用new关键字都会在堆内存开辟空间,都会创建一个对象。所以,如果多次使用匿名对象调用成员,实际上是创建了很多对象,调用了不同对象的成员,就不能保证对象的唯一性。

 

2,匿名对象可以作为参数进行传递。

如:
class Person
{
       private int age;
       private String name;
       
       public static void main(String[]args){
              show(new Person());//主函数中调用show方法,将匿名对象作为参数传递。
       }
       public static void show(Person p){//show方法接收Person类型的参数。
              p.speak();//Person类型变量p调用speak方法。
       }
       public static void speak(){
              System.out.println(name+":"+age);
       }
}


  

3.8基本类型参数和引用类型参数

class Demo
{    
       publicstatic void main(String []args){
              intx=3;
              show(x);
              System.out.println(x);//打印结果是:3
 
       }
       publicstatic void show(int x){
              x=13;
       }
}


 

    主函数中局部变量x的初始化值是3,调用show()方法后,局部变量x的值依然没变还是3,说明主函数的局部变量x只是将值传递给show()方法的另一个局部变量x,show()方法中局部变量的变化,随着show()方法的弹栈就会释放,不会影响到主函数中局部变量x的值。

引用数据类型参数传递:

class Person
{
       privateint age;
       privateString name;
       publicstatic void main(String []args){        
              Personp =new Person();//创建Person类的对象。
              System.out.println(p.age+","+p.name);//显示对象的age、name属性值。
             
              show(p);//将p变量作为参数传递给show()方法。
              System.out.println(p.age+","+p.name);//输出调用show()方法后的age、name属性值。
             
       }
 
       publicstatic void show(Person p){//接收引用类型Person类型的参数
              p.age=20;
              p.name="张三";
       }
}

  在主函数调用show(Person p)方法是,就是将主函数中的局部引用型变量p的地址值,赋值给了show()方法中的局部引用型变量p,这样show方法中的变量p具有和主函数的变量p一样的地址值,show()方法中的变量p也指向了Person类的对象。show()方法在执行过程中对Person类中的成员age和name进行了赋值,就改变了堆内存中Person()对象的age和name的值。show()方法调用后,再次输出Person对象的age和name属性时,他们的值都被改变了。

 

总结:基本类型参数的传递,是给不同的变量传递相同的值,是不会改变原始变量的原始值,而引用类型的变量作为参数传递,实际上传递的就是引用型变量的地址值,实际上就是不同的变量指向了同一个对象实体,对对象中成员的值修改,会影响到成员的原始值。

 

3.9构造函数

构造函数的特点:

1,  构造函数的函数名必须和类名一致。

2,  构造函数没有具体返回值。

3,  不需要定义返回值类型。

构造函数的作用:对对象进行初始化。(对象只有被初始化后才能使用)

构造函数的定义:

       权限修饰符构造函数名(参数列表……){

       执行语句;

       [return;]

       ……;

}

注意:如果类的权限是public,构造函数权限默认就是public;如果类的权限是默认,那么构造函数的权限就是默认权限。构造函数的权限可以指定其它权限,构造函数中的return是隐式语句。

什么时候定义构造函数?

构造函数中内部定义内容的就是对象一创建就具备的内容,如果想让对象一创建就具备某些内容,就可以把他们定义在构造函数中。

什么是默认构造函数函数?

在一个类中,如果没有自定义构造函数,那么类中会有一个隐式的默认空参数的构造函数。

注意:如果在类中定义了构造函数,那么默认的构造函数就不存在了;一个类中可以定义多个构造函数,这些构造函数是以重载的形式存在的,与一般函数的重载概念相同。

如:
class Person
{
       privateint age;
       privateString name;
 
       Person(){
       }
       Person(inta,String b){
              age=a;
              name=b;
       }
/*
上面的两个构造函数就是以重载的形式存在的:一个类中,相同的函数名,不同的参数列表。
*/
       publicvoid show(){
              System.out.println(name+":"+age);
       }
 
       publicstatic void main(String[]args){
              Personp1=new Person();//new Person()调用的就是空参数的Person(){}构造函数。
              Personp2=new Person(23,"张三");//这里调用的就是Person(int a,String b){age=a;name=b;}构造函数。
              p1.show();
              p2.show();
       }
}


总结:每次创建对象都会调用在创建对象时与传入参数对应的构造函数,如果没有传入参数默认会调用空参数的构造函数,对对象进行初始化。如果对应的构造函数不存在,那么在编译时就会报错。

构造函数和一般函数的区别:

构造函数:构造函数是在创建对象时,才被调用,创建一次对象,就调用一次构造函数。

一般函数:一般函数是在对象创建后或在其他的一般函数中被调用,可以进行一次或更多次的调用。

注意:构造函数可以调用一般函数,但一般函数是不能调用构造函数的。

 

4.0 this 关键字

this:所在函数所属对象的地址引用,总之,哪个对象调用了this所在的函数,那么this就是哪个对象的引用。

this的使用场景:

1,  当局部变量和成员变量同名是,用this区分,this.成员变量。

如:
class Person
{
       private int age;
       private String name;
 
       
       Person(int age,String name){
this.age=age;
this.name=name;
 /*this.成员变量与局部变量进行区分,将局部变量的值赋给成员变量局部变量与成员变量同名,提高了阅读性。*/
 
       }
       public void show(){
              System.out.println(name+":"+age);
       }
 
       public static void main(String[]args){
              Person p=new Person(23,"张三");
              p.show();
       }
} 

2,  构造函数与构造函数之间相互调用时。this()调用空参的构造函数,this(指定参数)就可以调用对应参数的构造函数。(当构造函数中用this调用其他构造函数是,this要放在构造函数第一行)

如:
class Person
{
       private int age;
       private String name;
       Person(String name){
              this.name=name;
       }     
       Person(int age,String name){
              this(name);//this(指定参数),调用Person(String name){this.name=name;}  构造函数。
              this.age=age;          
       }
       public void show(){
              System.out.println(name+":"+age);
       }
 
       public static void main(String[]args){
              Person p=new Person(23,"张三");
              p.show();
       }
}
  

4.1 static关键字(静态)

static静态修饰符:用于修饰成员。

static 修饰的成员特点:

1,  静态成员随着类的加载而加载。

2,  优先于对象存在。

3,  被所有对象共享。

4,  可以用类名.成员名调用,也可以用对象调用。

注意:

1,  静态方法只能访问静态成员。(非静态方法既能访问静态成员又能访问非静态成员)

2,  静态方法中不能用this、super关键字,因为静态优先于对象存在。

3,  主函数是静态的。 

什么是静态变量?

static修饰的成员变量,可以用类名直接调用。也称为类变量。

成员变量和静态变量的区别:

1,  生命周期不同

成员变量:随着对象的创建而存在,随着对象的回收而释放。

静态变量:随着类的加载而存在,随着类的消失而消失。

2,  调用方式不同

成员变量:只能用对象调用。

静态变量:既能用对象调用,又可以使用类名调用。

3,  别名不同

成员变量:又称为实例变量。

静态变量:又称为类变量。

4,  存储位置不同

成员变量:存储在堆内存的对象中。

静态变量:存储在方法区的静态区,因为被所有对象共享,也称为共享数据区。

 

什么时候定义静态变量和静态函数?

1,  静态变量:当对象中成员变量的值都是相同的,这个成员变量就可以定义为静态变量。

2,  静态函数:取决于该函数是否访问对象中的特有数据,如果不访问特有数据就可以加static修饰符,否则,就不能定义为静态函数。

静态代码块

static修饰的代码块

如:

static{

//要执行的内容;

}

静态代码块的特点:随着类的加载而执行,无论类加载几次静态代码块只执行一次。

静态代码快的作用:给类进行初始化。 

4.2final关键字

final关键字可以用来修饰类、方法、变量。

final修饰的类,不能被继承。

final修饰的方法,不能被覆盖。

final修饰的变量,是一个常量,只能被赋值一次。

注意:为了区分常量和变量,final修饰的变量,变量名都必须大写,多个单词之间用下划线分开。      

4.3构造代码块

什么是构造代码块?

定义在类中的代码块

如:

class Demo{ 

    {

       //构造代码块

    }

}

构造代码块的作用:给所有对象初始化。

注意:每次创建对象都会调用构造代码块,有几个构造代码块,就执行几个。

  构造函数和构造代码块的区别?

  在创建对象时,构造函数和构造代码块都会被调用,但是构造函数的调用和执行是有针对性的,会根据创建对象时是否传入参数,找到空参数的构造函数或匹配参数的构造函数再去执行;而对于构造代码块来说只要创建了对象,就会调用构造代码块,有几个调用几个。总的来说,构造函数的执行有针对性,而构造代码块没有。 

静态代码块、构造代码块和构造函数的使用.

如:
class Person
{
       {
              System.out.println("构造代码块");
       }
       
       static{
              System.out.println("静态代码块");
       }
       Person()
       {
              System.out.println("构造函数");
       }
       
}
class Demo
{
       public static void main(String[]args){
              Person p=new Person();
              Person p1=new Person();
       }
}
/*
输出结果:
静态代码块
构造代码块
构造函数
构造代码块
构造函数
*/


 

可见,依次执行顺序是;静态代码块(随着类的加载只执行一次)--->构造代码块->构造函数.

但是,实际代码的执行过程中还是先执行构造函数中的隐式语句super(). 然后进行类中成员变量的显示初始化,再执行构造代码块,构造代码块执行完后,才真正执行构造函数中的语句,对对象进行初始化.

如:
publicclass Demo{
   publicstaticvoid main(String[] args) {
         new Zi();//创建Zi类对象
   }
}
class Fu{
   intnum=5;
   {
      System.out.println("Fu构造代码块");
   }
   Fu(){//第三步:执行Fu类的构造函数,这里的super会找到Object类的构造函数.直到执行完毕
      super();//隐式语句(去找Object类的构造函数,这里省略)
      //显示初始化.    第四步:对Fu类中的成员变量进行显示初始化.
      //执行构造代码块第五步:如果Fu类中有构造代码块,则执行构造代码块.
      show();         //第六步:调用show()方法,因为是创建Zi类对象,所以调用Zi类的show()方法.
   }
   void show(){
      System.out.println("Fu show"+5);
   }
}
class Zi extends Fu{
   intnum=9;
   {
      System.out.println("Zi构造代码块"+num);
      
   }
   Zi(){//第一步:调用Zi类的构造函数
      super();//隐式语句   第二步:执行super语句,跳到Fu类的构造函数,直到执行完毕
      //显示初始化.//第七步:对Zi类的成员变量进行显示初始化.
      //执行构造代码块//第八步:执行Zi类中的构造代码块.
      System.out.println("Zi constructor"+num);//第九步:执行输出语句.
   }
   void show(){
      System.out.println("Zi show"+num);
   }
}
/*结果:
Fu构造代码块
Zi show0
Zi构造代码块9
Zi constructor9
*/


 

总结:由此可见,构造函数还是先执行的,只不过,是在执行完隐式语句super()后,执行构造代码块,然后再执行构造函数中的代码.

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值