Java类与对象概述(一)

1. 面向对象特征(三大基本特征)

面向对象最大特征:对现实生活可以进行抽象。举个简单的例子,把一个大象关进冰箱里,对于面向过程而言,首先把冰箱门打开,其次把大象放进去,最后关上冰箱门;但面向对象始终关心的是大象这个实体,不关心这些步骤。

  • 封装:把客观事物封装成抽象的类,并且类把自己的方法和数据,只让可信的类或者对象操作,对不可信的信息进行隐藏。即就是,内部操作对外部而言不可见
  • 继承:实现现有类的功能,并对原有类的功能进行扩展创新
  • 多态:多态就是一个类实例的相同方法在不同情形有不同表现形式

2. 类与对象的定义与使用

2.1 基本概念

  • 类:具有相同事物的集合
  • 对象:一个具体的、可以使用的事物
  • 类的组成:属性和方法

2.2 定义和使用

例如:一个Person类的定义

class Person{
	public String name;            //属性
	public int age;				//属性

	public Person(String name, int age){        //构造方法
		this.name = name;         //this.xxx表示当前类的属性
		this.age = age;
	}

	public String getPersonInformation(){       //普通方法
		return "姓名:"+this.name+",年龄:"+this.age;
	}
}

有了类,即可以定义对象,语法:类名称 对象名称 = new 类名称();
以上述Person类为例,用来产生Person类的一个实例

Person person = new Person("张三", 20);         //new关键字,代表开辟了一块内存
Person person1 = new Person("李四"21)

有了对象,我们可以用对象调用实例属性(public修饰)和方法

Person person = new Person("张三"20);
System.out.println(person.name);
System.out.println(person.getPersonInformation());

2.3 对象内存分析

Java内存分为栈内存和堆内存

  • 栈内存:存放的是局部变量(基本数据类型,对象引用)
  • 堆内存:保存真正的数据。即对象的属性信息

比如上述的例子中,Person person = new Person("张三", 20);,new关键字,表示在堆内存分配了内存,并且产生了Person类的对象person引用这块内存。
刚开始堆内存中:name = null, age = 0,栈中的person(0x0001)指向这块堆内存
当构造方法一执行结束,name = "张三", age = 20,
针对以上,注意的几点如下:

  • 对象(引用数据类型)必须在实例化后调用,否则会产生NullPointException(运行错误),但编译不会出错
  • 垃圾空间:没有任何栈内存指向的堆空间
  • 所有的垃圾空间会不定期GC,GC会影响性能,所以要减少无用对象的产生

3. 封装和构造方法

3.1 用private实现封装

让内部操作对外部不可见,即不能用对象直接操作属性,可以使用private

	private String name;
	private int age;

一旦使用了private,要访问私有属性时,有两种方法

  • setter方法:主要对属性内容进行修改与设置
  • getter方法:获取属性内容

例如:扩展上述Person类的内容

class Person{
	private String name;            //只允许本类访问,不允许外部类访问
	private int age;

	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return this.name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return this.age;
	}

	public String getPersonInformation(){
		return "姓名:"+this.name+",年龄:"+this.age;
	}
}
public class TestPerson{
	public static void main(String[] args){
		Person person = new Person();
		person.setName("张三");
		person.setAge(20);
		System.out.println(person.getPersonInformation());
	}
}

类的设计原则:

  • 编写类时,类中的所有属性必须使用private封装
  • 属性如果要被外部访问,必须定义setter、getter方法

3.2 构造方法

产生对象类名称 对象名称 = new 类名称();
其实构造方法就是使用关键字new实例化新对象时来进行调用的操作方法
对构造方法的定义,需要遵循以下原则:

  • 1.方法名称必须与类名称相同
  • 2.构造方法没有返回值类型声明
  • 3.每一个类中至少存在一个构造方法(没有明确定义,系统自动生成一个无参构造

构造方法无返回值,为什么没有void声明?分析如下:

  • 1.属性是在对象开辟堆内存时开辟的空间
  • 2.构造方法是在使用new后调用的
  • 3.普通方法是在空间开辟了、构造方法执行之后多次调用的
	public void Person(){}  //命名不标准的普通方法
	public Person(){}      //无参构造方法

因此,编译器是根据程序结构来区分普通方法与构造方法,所以构造方法没有返回值类型声明
若类中定义了构造方法,则默认的无参构造将不再生成
比如上述中的Person类:

	public Person(String name, int age){      //两个参数
		this.name = name;
		this.age = age;
	}

构造方法的调用和内存分配几乎是同步完成的,因此我们可以利用构造方法来为类中的属性进行初始化操作(避免多次setter调用)

3.3 构造方法重载

  • 构造方法按照参数个数升序或者降序
	public Person(String name){
		this.name = name;
	}
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}

3.4 匿名对象

  • 没有任何栈空间指向,使用一次就成为垃圾空间
class Person{
	private String name;
	private int age;

	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}

	public void getPersonInformation(){
		System.out.println("姓名:"+this.name+",年龄:"+this.age);
	}
}
public class TestPerson{
	public static void main(String[] args){
		new Person("张三"20).getPersonInformation();    //匿名对象
	}
}

4. this关键字

this关键字有三个用途:

  1. this调用本类属性
  2. this调用本类方法
  3. this表示当前对象

4.1 this调用本类属性

在上述的Person类中,当参数与类中属性同名时,类中的属性无法被正确赋值。因此加上this关键字可以正确的给对象属性赋值

	this.name = name;
	this.age = age;

只要在类中访问类中的属性,一定要加上this关键字

4.2 this调用本类方法

  • this调用普通方法:this.方法名称(参数)
  • this调用构造方法:this(参数)
    举例:this调用普通方法
class Person{
	private String name;
	private int age;

	public Person(String name, int age){
		this.name = name;
		this.age = age;
		this.print();       //this调用普通方法
	}
	public String getPersonInformation(){
		return "姓名:"+this.name+",年龄:"+this.age;
	}
	public void print(){
		System.out.println("**************");
	}
}
public class TestPerson{
	public static void main(String[] args){
		Person person = new Person("张三", 20);
		System.out.println(person.getPersonInformation());
	}
}

调用普通方法不需要加上this也可以正常调用,但加上可以区分方法的定义来源
举例:this调用构造方法

class Person{
	private String name;
	private int age;

	public Person(){
		System.out.println("*******构造方法********");
	}
	public Person(String name){
		this();             //调用本类无参构造
		this.name = name;
	}
	public Person(String name, int age){
		this(name);        //调用本类有参构造
		this.age = age;
	}
	public String getPersonInformation(){
		return "姓名:"+this.name+" 年龄:"+this.age;
	}
}
public class TestPerson{
public static void main(String[] args){
		Person person = new Person();
 		System.out.println(person.getPersonInformation());
  		Person person1 =new Person("张三");
  		System.out.println(person1.getPersonInformation());
  		Person person2 = new Person("李四", 18);
  		System.out.println(person2.getPersonInformation());	
	}
}
/*
********构造方法************
姓名:null 年龄:0
********构造方法************
姓名:张三 年龄:0
********构造方法************
姓名:李四 年龄:18
*/

在用this调用构造方法时,语句必须在构造方法首行

4.3 this表示当前对象

举例:this表示当前对象

class Person{
	private String name;
	private int age;
	
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public void print(){
		System.out.println("PRINT方法"+this);
	}
}
public class TestPerson{
	public static void main(String[] args){
		Person person = new Person("张三", 20);
		person.print();
		System.out.println("MAIN方法"+person);
	}
}
/*
PRINT方法Person@15db9742
MAIN方法Person@15db9742
*/

5. static关键字

5.1 static类属性

  • 传统属性保存在堆内存中,且每个对象独享属性
  • static属性又称类属性,保存在全局数据区的内存中,所有对象都可以进行数据区的访问
    举例:含有static属性
class Person{
	private String name;
	private int age;
	private static String country = "China";
	
	public Person(Stirng name, int age){
		this.name = name;
		this.age = age;
	}
	public String getPersonInformation(){
		return "姓名:"+this.name+",年龄:"+this.age+",国家:"+Person.country;
	}
}
public class TestPerson{
	public static void main(String[] args){
		Person person = new Person("张三", 20);
		System.out.println(person.getPersonInformation());
	}
}
//姓名:张三,年龄:20,国家:China

结论

  • 访问static属性应使用类名称.属性名
  • 所有非static属性(实例变量)必须在对象实例化使用,而static属性不受对象实例化控制
  • 当我们修改country属性时,所有属性值都同步此属性值

5.2 static类方法

举例:static方法

class Person{  
	private String name;  
	private int age;  
	private static String country = "China";  
	public Person(Stirng name, int age){
  		this.name = name;
  		this.age = age;
 	}

	public static void setCountry(String country){
		Person.country = country;        //此处不能使用this.country,静态方法不能访问非静态属性
	}
 	public String getPersonInformation(){
  		return "姓名:"+this.name+",年龄:"+this.age+",国家:"+this.country;    //此处的Person.country可以用this.country替换,非静态方法可以访问静态属性
 	}
}
public class TestPerson{
 	public static void main(String[] args){
  		Person person = new Person("张三", 20);
  		System.out.println(person.getPersonInformation());
  		Person.setCountry("American");
  		System.out.println(person.getPersonInformation());
 	}
}
/*
姓名:张三,年龄:20,国家:China
姓名:张三,年龄:20,国家:American
*/

结论

  • 所有的static方法不允许调用非static定义的属性或方法
  • 所有的非static方法允许访问static方法或属性
  • main方法是一个特殊的static方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值