黑马程序员----java面向对象01(封装、静态)

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


一.面向对象的概念理解

1、把复杂的问题简单化了

2、面向过程相当于一个执行者的行为,而面向对象相当于一个指挥者的行为

3、面向对象就是把一系列行为和属性封装起来,然后通过直接调用拥有这些行为和属性的实体也就是对象来实现功能操作

4、面向对象中如果有我所需要的功能的对象(查阅API),直接调用此对象即可;如果没有我需要的,那么我需要自己创建对象并定义功能

 

二.类与对象的关系

1、类就相当于制作汽车的图纸,而对象就相当于制作出来的汽车实体

2、应该是先有对象,然后才有类,因为只有有了对象实体以后,对此实体进行抽象,然后形成类

 

三.成员变量与局部变量的区别

1、成员变量在本类中都可以访问,而局部变量只能在本函数或行为体中被访问

2、成员变量随着对象的创建而产生,存在于堆内存中;局部变量存在于栈内存中

3、成员变量有默认初始化值null或0;局部变量没有默认初始化值,不被初始化不能使用

 

四.创建对象,使用对象

public class CarDemo {
	public static void main(String[] args) {
		//1、创建一个对象c
		//Car c = new Car();  //new Car就是创建一个车对象,名字是c,颜色是红色,轮胎数是4
		//c.color="蓝色";  //改变c车的颜色。   注意:并没有改变“图纸”的颜色,只是改变了c车的颜色而已
//		c.run();      //  哪个对象调用的run,就是打印的那个对象的color和num
		
		//2、匿名对象(new Car())
		//Car c= new Car(); 
		compare(new Car());
		//c.color="黄色";    
		
		new Car().color="黄色";   //创建了一个新对象,改变了此对象的颜色 
		new Car().num=9;     //又创建了一个新对象,改变了此对象的轮胎数
			
		/*
		 * 总结:
		 * 匿名对象只能用来调用方法,匿名对象调用属性是没有意义的,因为每new一次都是创建了一个新的对象,并不是对原来的属性值进行改变
		 *	        
		*/
	}
	
	public static void compare(Car c){
		c.color = "black";
		c.num = 6;
	}
}


//定义一个车类(抽象的)
class Car
{
	//车的颜色
	String color="红色";    
	//车的轮胎数
	int num=4;
	
	//车跑起来
	void run()
	{
		System.out.println("颜色是"+color+",轮胎数是"+num);
	}
}
 

 


 内存结构图:

 

 

 

 五.匿名对象

1、顾名思义就是没有具体的名字的对象,每new一次都是创建了一个新的对象,故调用此对象方法时只能使用一次
/*
* 总结:
* 匿名对象只能用来调用方法,匿名对象调用属性是没有意义的,因为每new一次都是创建了一个新的对象,并不是对原来的属性值进行改变
*       
*/


经典例子需求,创造一个汽车修配厂,对进来的汽车进行颜色或轮胎数的更改



六.封装(private)

1、封装是指隐藏对象的属性和方法,仅对外提供访问接口即可,这样提高了程序的安全性,例如电脑机箱内部构造很复杂,但没必要让用户看到,只需要提供给用户背后插口即可。

2、对属性的封装在数据类型前加上private,并且提供set、get方法进行设置值和返回值

3、private用于修饰成员变量和成员函数

例子:控制传入的年龄是否为负数

public class Fengzhuang {
	public static void main(String[] args) {
		Person4 p = new Person4();
		p.setAge(39);   //传入的年龄为负数或者是正数
	}
}

class Person4{
	private int age;      //属性基本上全部都要私有化
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		if(age>0 && age<130){     //在此判断下传入的年龄是否合法
			this.age = age;
			speak();
		}else{
			System.out.println("您输入的年龄有误!");
		}
	}
	void speak(){
		System.out.println("age是:"+age);
	}
}

 

七.构造函数

1、构造函数名与类名一致

2、构造函数可以重载,参数列表不一致

3、构造函数的作用是对对象进行初始化,一般对象再被创建时就拥有了一些属性,这时候就用到了构造函数

4、对于禁止创建对象的类,可以把此构造函数私有化,这样就无法创建对象了

代码示例:

/*什么时候需要构造函数:当一个对象一被创建就有默认的属性或功能时需要定义
 * 
 * 
 * 用一个刚出生的小孩举例讲解
 * 1、刚出生有的有姓名,有的没有姓名:构造函数的重载,函数名一致,参数列表不一致
 * (注意!!:一旦自定义了构造函数,那么如果在创建对象时必须调用相同参数列表的构造函数)
 * 2、刚出生都会哭,在以后的成长中也会哭:构造函数中调用哭的方法,对象创建完后也可以调用哭的方法
 * 3、构造函数只能是在对象创建时被调用,每调用一次都是创建了一个新的对象,
 *    故要想给属性赋予新的值,只能通过(对象.函数名)来赋值,而不能通过再一次创建对象改变,这样是创建了一个新的对象
 * 4、如果禁止创建对象,可以把此构造函数私有化    private Person{}
 * */

public class Gouzaohanshu {
	public static void main(String[] args) {
		//1、分别是调用的不同构造函数
		Person5 p1 = new Person5();     
		Person5 p2 = new Person5("张三");
		Person5 p3 = new Person5("李四",30);
		
		p1.cry();     //2、p1在以后的成长中还会哭
		
		p1.setAge(50);
		System.out.println(p1.getAge());      //3、在这里改变年龄只能通过对象调用函数去改变,而不能通过创建对象传值去改变
	}
}

class Person5{
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	Person5(){      //!!!如果把这个构造函数注释,那么p1对象时无法被创建的
		cry();
	}
	Person5(String name){
		this.name = name;
		cry();
	}
	Person5(String name,int age){
		//this.name = name;
		this(name);           //this在构造函数之间的相互调用,(!!注意:此语句只能放在函数中的第一行)
		this.age = age;
		cry();
	}
	
	void cry(){
		System.out.println("哭");
	}
}


八、构造代码块

1、构造代码块优先于构造函数执行

2、构造代码块是在对象被创建时执行,并且只执行一次(每创建一此对象就执行一次)

代码示例:

//构造函数与构造代码块的区别
/*
 * 不论什么对象被创建都会首先调用构造代码块,然后再调用相对应的构造函数(优先级)
 * 
 */


public class Gouzaodaimakuai {
	public static void main(String[] args) {
		Person p1 = new Person();  //定义一个对象p1
		Person p2 = new Person("张三");  //定义一个对象p2
		p2.speak();
	}
}

class Person
{
	private String name;
	private int age;
	
	//构造方法一
	Person()
	{
		System.out.println("已调用构造函数");
	}
	
	//构造代码块
	{
		System.out.println("已调用构造方法");
	}
	
	//构造方法二
	Person(String name)
	{
		this.name = name;
	}
	
	//构造方法三 
	Person(String name,int age)
	{
		name = name;
		age = age;
	}
	
	public void speak()
	{
		System.out.println("name的值是:"+this.name);
	}
}

	
 


九.this关键字

/*
 * this的应用:定义一个比较两个人年龄是否相同的功能,也就是是否是同龄人
 * 思路
 * 1、定义一个人类,并设置年龄属性
 * 2、定义一个构造函数,用于初始化年龄
 * 3、定义一个比较年龄的函数,(注意!!这个函数是由两个人中的一个来调用,所以只需要定义另外一个人的年龄作为参数即可)
 * */

        public class This {
	
	public static void main(String[] args) {
		Person1 p1 = new Person1(20);
		Person1 p2 = new Person1(30);
		//Person1 p = new Person1(0);
		//System.out.println(p.compare(p1, p2));	
		System.out.println(p1.compare(p2));        //p1调用compare方法与p2的年龄进行比较
	}

}

class Person1{
	private int age;
	
	Person1(int age){
		this.age = age;
	}
	public boolean compare(Person1 p){
		return this.age==p.age;      //对于布尔型返回值,不需要定义if语句去判断,直接返回结果即可
	}
} 

 

十.static关键字的运用

/*
 * static :是一个修饰符,用于修饰成员(成员变量和成员函数)
 * 1、可以直接别类名调用
 * 2、静态成员随着类的加载而加载,随着类的消失而消失。类一被加载,静态成员就存在于方法区(共享区)中了
 * 3、静态成员优先于对象存在,因为在类被加载之前对象不是存在的,所以对象是可以调用静态成员的
 * 4、静态成员被所有对象所共享
 * 5、静态成员可以直接被类名调用:(类名.静态成员)
 * 
 * 类变量和实例变量的区别
 * 1、存放位置
 * 类变量存在与方法区(共享区)中
 * 实例变量存在与堆内存中
 * 2、生命周期
 * 类变量随着类的加载而产生,随着类的消失而消失(长)
 * 实例变量随着对象的创建而产生,随着对象的消失而消失(短)
 * 
 * 
 * 静态的利处与弊端
 * 利处
 *  把共有的数据存储在共享区中,节省空间
 *  可以直接被类名调用
 * 弊端
 *  生命周期太长
 *  静态成员只能访问静态成员 
 * */

public class Static_Demo {
	public static void main(String[] args) {
		Person p = new Person();
		p.name = "张三";
		p.print();
	}
}

class Person{
	String name;       //定义姓名  ,又称为成员变量或实例变量
	
	//定义国籍,在前面加上static以后,运行没有改变,但是内存中发生了变化,country不存在堆内存中了,提取出来共享
	//又称为静态成员变量或类变量
	static String country = "CN";    
	
	void print(){
		System.out.println(name+":::::::"+country);
	}
}
 

----------------------------------------------------------------------------------------------------


/*
 * 静态代码块,格式:static{  }
 * 静态代码块优先于主函数执行,并且只在类第一次被加载时执行,是用来给类进行初始化的
 * 
 * 执行顺序:静态代码块(类加载)------>默认初始化(0或null)----->显示初始化(本来有值的)----->构造代码快(对象)------>构造函数(有参数的话赋值)
 * 
 * 
 *   Person p = new Person("张三",4);
 * 此句话执行顺序:
 * 1、因为new用到了Person.class文件,所以首先把类加载到堆内存中,开辟空间,并且运行static静态代码块
 * 2、然后属性进行默认初始化,也就是0或者null,age=0,
 * 3、再次属性进行显示初始化,也就是age=3,
 * 4、因为创建了对象,所以调用了构造代码块,记住,构造代码块是所有对象被创建时都会调用的,而构造函数只是针对特定对象而被调用
 * 5、最后调用了构造函数,并传入参数进行赋值操作"张三",4
 * 6、将内存地址赋给对象P
 * */

public class Static_code {
	public static void main(String[] args) {
		Code.show();
	}
		
	static{
		System.out.println("b");
	}
}

class Code{
	static{
		System.out.println("a");
	}
	
	public  static void show(){
		System.out.println("c");
	}
}
 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值