面向对象(上)

课程大纲:

1.面向对象基本概念

2.类与对象

3.类与对象的定义格式

4.对象与内存分析

5.封装性

6.构造方法

7.this关键字

8.值传递与引用传递

9.对象的一对一关系

10.static关键字

11.main方法分析

12.代码块

13.单列设计模式

14.对象数组与管理

1.面向对象基本概念

一.什么是面向对象:

1.面向对象是一种编程思想.

2.面向对象是一种思考问题的思维方式

二.建立面向对象思维方式:

1.先整体,在布局

2.先抽象再具体

3.能做什么,再怎么做

三.如何学习面向对象:

1.掌握一门面向对象语言的语法

2.熟悉面向对象的设计原则

3.熟悉面向对象设计模式

2.类与对象

什么是类?

1.类是:分类,类别

2.通过分类,我们可以区别不同的事物种类,再日常生活中,我们常常这样做

3.所以,类是一种具有相同特性(属性)与行为(方法)的事物集合

类与对象的关系

1.类表示一个共性的产物,是一个综合的特征,而对象,是一个 个性的产物,是一个 个体的特征.

2.类由属性和方法组成:

属性:就相当于一个个的特征

方法:就相当于人的一个个的行为,例如:说话,唱歌,睡觉.

3.类和对象的定义格式

在java中可以使用以下的语句定义一个类

clss 类名称{

属性名称;
返回值类型 方法名称(){}

}

对象的定义:

一个类想要真正的进行操作,则必须依靠对象,对象的定义格式如下:

类名称对象名称 = new 类名称();

按照以上的格式就可以产生对象了。

如果要想访问类中的属性或方法(方法的定义)。

则可以依靠以下的语法形式:

访问类中的属性:

对象.属性;

访问类中的方法:

对象.方法();

在java中对象声明有两种含义

声明对象:Horse horse = null;

//表示声明了一个对象,但是此对象无法使用,horse没有具体的内存指向。

实例化对象:horse = new Horse();

//表示实例化了对象,可以使用

//通过对象调用方法:

hors.eat()

//匿名对象调用方法:

new Horse().eat()

/**
	面向过程:以步骤为单位,一步一步完成某一个具体事情
	面向对象:以对象为单位,通过调度组合不同的对象来完成某一个事情
*/

public class Test1{
	
	public static void main(String[]args){
	
		Horse h =null; //声明一个类的变量(除了8种基本数据类型以外,都是引用数据类型,包括数组)
		
		
		//创建一个Horse类型的对象,实例化对象
		
		h = new Horse();
		//有了对象,我们就可以调用对象的属性和方法
		h.name = "老八";
		h.age = "牛逼";
		h.run();//调用方法,那么方法就会被执行
		h.eat();
		
		//匿名对象:只能使用一次,用完后该对象会被释放
		new Horse().eat();
		h = null;//把对象释放
		//h.eat();//当对象不存在时,调用该对象的属性和方法将报错(空指针)
	}
}
	//自定一个类(类型)
	class Horse{
		//在类中定义属性(特征)
		String name;
		
		String age;
		public void run(){
			System.out.println("我是"+name+",我可"+age+"了");
		}
		public void eat(){
			
			System.out.println("我每天都吃奥里给,一天吃两斤,越吃越牛逼!");
		}
	}

4.对象内存分析

1.new关键字表示创建一个对象

2.new关键字表示实例化

3.new关键字表示申请内存空间

注意:如果使用一个没有申请内存空间的对象,会报空指针异常;

java.lang.NullPointerException

类与对象小结

1).new关键字,表示向内存申请空间,也表示实例化一个对象,创建一个对象.

2).一个对象在内存中的大小,由该对象的所有属性所占的内存大小的总和.引用类型变量在32位系统上占4个字节,在64位系统上占8个字节.加上而外的对象隐性数据所占的大小.

3).相同的类型猜可以赋值.

4).不同的引用,指向同一个对象,任何一个引用改变对象的值,其他引用都会反映出来.

5).编程时要注意的问题:在确定不使用对象时,要尽早释放对象:引用 = null;

6).当一个堆中的对象没有被任何引用变量所指向时,该对象会被JVM的GC程序认为是垃圾对象,从而被回收.

5.封装性

一.封装性的概念

1.封装性是面对对象思想的三大特点之一.

2.封装就是隐蔽实现细节,仅对外提供访问接口.

        封装有:

        属性的封装,方法的封装,类的封装,组件的封装,模块化封装,系统级封装...

二.封装的好处

1.模块化

2.信息隐藏

3.代码重用

4.插件化易于调试

5.具有安全性

封装缺点:

会影响执行效率

/**
	封装性
	如果属性没有封装,那么在本类之外创建对象后,可以直接访问属性
	private关键字:访问权限修饰符,public(公开)private(私有的)私有的属性或方法只能在本类中访问;
	公有的属性和方法可以被类外部 的其他类访问,想要在类外部访问私有属性,我们需要提供公有的方法来间接访问
	通常在一个类中,属性都私有化,并对外提供getter and setter 方法
*/
public class Test2{
	
	public static void main(String[]args){
		
		person p1 = new person();
		//p1.name = "菲菲";
		//p1.age = 18;
		
		p1.setName("菲菲");
		p1.setAge(188);
	}
}

//没有封装之前
class person{
	//属性的封装
	private String name;
	private int age;
	
	//getter and setter
	
	//对外提供一个为name属性设值的方法
	public void setName(String name){
		this.name = name;
		
	}
	//对外提供一个获取name属性的方法
	public String getName(){
		
		return name;
	}
	public void setAge(int age){
		
		
		this.age = age;
	}
	public int getAge(){
		
		return age;
	}

}

三.成员变量和局部变量

1.在类中的位置不同

        成员变量:在类中定义

        局部变量:在方法中定义或者方法的参数

2.在内存中的位置不同

        成员变量:在堆内存(成员变量属于对象,对象进对内存)

        局部变量:在栈内存(局部变量属于方法,方法进栈内存)

3.生命周期不同

        成员变量:随着对象的创建而存在,随着对象的销毁而消失

        局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

4.初始化值不同

        成员变量:有默认初始值,引用类型默认为null

        局部变量:没有默认初始值,必须定义,赋值,然后才能使用

注意:

        局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则

6.构造方法

什么是构造方法

1.构造方法就是类构造对象时调用的方法,用于对象的初始化工作

2.构造方法是实例化一个类的对象时,也就是new的时候,最先调用的方法

构造方法的定义:

构造方法是在类中定义的,构造方法的定义格式:方法名称与类名称相同,无返回值类型的声明

对象的实例化语法:

Dog dog = new Dog();//new Dog后面有个括号,带括号表示调用了方法,此时调用的方法就是构造方法了

构造方法重载:

无参构造方法:

public Dog(){}

带一个参数的构造方法:

public Dog(String name){
    this.name = name;
}

带多个参数的构造方法:

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

构造方法小结

1).构造方法名称与类名相同,没有返回值声明(包括void)

2).构造方法用于初始化数据(属性)

2).每一个类中都会有一个默认的无参的构造方法

4).如果类中有显示的构造方法,那么默认的构造方法将无效

5).如果有显示的构造方法,还想保留默认构造方法,需要现实的写出来

6).构造方法可以有多个,单参数不一样,成为构造方法的重载

7).在构造方法中调用另一个构造方法,使用this(...),该句代码必须在第一句

8).构造方法之间的调用,必须要有出口

9).给对象初始化数据,可以使用构造方法或stter方法,通常情况下,两者都会保留

10).一个好的编程习惯是要保留默认的构造方法.(为了方便一些框架代码使用反射来创建对象)

11).private Dog(){},构造方法私有化,当我们的需求是为了保证类只有一个对象时.

什么时候一个类只需要一个对象?比如,工具类(没有属性的类,只有行为)并且该工具对象被频繁使用.权衡只用一个对象与产生多个对象的内存使用,来确定该类是否要定义为只需要一个对象.

7.this关键字

在java基础中,this关键字是一个最重要的概念,使用this关键字可以完成以下的操作:

        调用类中的属性

        调用类中的方法或者构造方法

        表示当前对象

/** 
	this关键字
	调用类中的属性
	调用类中的方法或构造方法
	表示当前对象:在方法被调用的过程中,哪个对象调用了方法,在方法内的this就表示谁
	类名.this
*/
public class Test4{
	
	public static void main(String[]args){
		
		Cat cat = new Cat();
		cat.setName("狗蛋");
		cat.setAge(9);
		cat.eat();
	}
}
class Cat{
	
	private String name;
	private int age;
	public void setName(String name){//name = 狗蛋
		this.name = name;//this代表的时当前对象
	}
	public String getName(){
		
		return name;
	}
	public void setAge(int age){
		
		this.age = age;
	}
	public int getAge(){
		
		return age;
	}
	public void eat(){
		//在方法中使用this调用类中的其他方法或属性,this可以省略,this前面可以使用当前的类名.this
		//在后面的内部类知识点中会涉及到
		System.out.println("我是"+this.getName()+"我"+this.age+"岁了,"+"我爱吃粑粑");
//或 System.out.println("我是"+Cat.this.getName()+"我"+this.age+"岁了,"+"我爱吃粑粑");
	}
}

8.值传递与引用传递

示例一:        值传递

public calss ValueDemo{
    public static void main(String[]args){
        int x = 10;
        method(x);
        System.out.println("x="+x);
    }
    public static void method(int mx){
        mx = 20;
    } 
}

示例二:        引用传递

public class RefDemo1{
    public static void main(String[]args){
        Duck d = new Duck();
        method(d);
        System.out.println("Duck age="+d.age);
    }
    public static void method(Duck duck){
        duck.age = 5;
    }
}
class Duck{
    int age = 2; //省略封装
}

示例三:        String传递

//示例三:String传递

public class RefDemo2{
	
	public static void main(String[]args){
		
		String name = "小飞";
		method(name);
		System.out.println("name="+name);
		
	}
	public static void method(String sname){
		
		sname = "小贝";
	}
}

示例四:        String传递

//示例四:String传递

public class RefDemo3{
	
	public static void main(String[]args){
		
		Person p = new Person();
		method(p);
		System.out.println("Person name="+p.name);
	}
	public static void method(Person per){
		
		per.name = "备备";
	}
}
class Person{
	
		String name = "飞飞";//省略封装
}

9.对象的一对一关系

两个对象之间的一对一关系:

比如:

一个英雄(Hero)对一个兵器(Weapon)

代码如何表示?

/** 
	两个对象之间的一对一关系:
	比如:一个英雄(Hero)对一个兵器(Weapon)
	双向一对一
	单向一对一
*/
public class Test5{
	
	public static void main(String[]args){
		Hero hero = new Hero("刘备",300);
		Weapon weapon = new Weapon("双股剑",99);
		//把两个对象关联起来
		hero.setWeapon(weapon);
		weapon.setHero(hero);
		
		//通过英雄来获取他的信息
		String name = hero.getName();
		int age = hero.getAge();
		Weapon w = hero.getWeapon();
		System.out.println("我是"+name+"我"+age+"岁,我的武器是"+w.getName()+",排行"+w.getGrade()+"位");
		
	}
}
//英雄类
class Hero{
	private String name;
	private int age;
	private Weapon weapon;//一对一关系
	public void setWeapon(Weapon weapon){
		this.weapon = weapon;
	}
	public Weapon getWeapon(){
		return weapon;
	}
	public Hero(){}
	public Hero(String name,int age){
		this.name = name;
		this.age = age;
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		
		return name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return age;
	}
}
//兵器类
class Weapon{
	
	private String name;
	private int grade;
	private Hero hero;
	public void setHero(Hero hero){
		this.hero = hero;
	}
	public Hero getHero(){
		return hero;
	}
	public Weapon(){}
	public Weapon(String name,int grade){
		this.name = name;
		this.grade = grade;
		
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public void setGrade(int grade){
		this.grade = grade;
	}
	public int getGrade(){
		return grade;
	}
}

10.static关键字

static关键字的作用:

1.使用static关键字修饰一个属性

        声明为static的变量实质上就是全局变量

2.使用static关键字修饰一个方法-

        通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法

3.使用static关键字修饰一个类(内部类)

/** 
	static 关键字
	1.静态变量或方法不属于对象,依赖类
	2.静态变量是全局比变量,生命周期从类被加载后一直到程序结束
	3.静态变量只有存一份,在静态方法区中存储0
	4.静态变量是本类所有对象共享一份
	5.建议不要使用对象名去调用静态数据,直接使用类名调用
	6.static修饰一个方法,那么该方法属于类,不属于对象,直接用类名调用
	7.静态方法只能访问静态属性和方法
*/


public class Test6{
	
	public static void main(String[]args){
		//Role beibei = new Role("刘备","蜀国");
		//Role yunchang = new Role("关羽","蜀国");
		//Role feifei = new Role("张飞","蜀国");
		Role beibei = new Role("刘备");
		Role yunchang = new Role("关羽");
		Role feifei = new Role("张飞");
		System.out.println(beibei.getInfo());
		System.out.println(yunchang.getInfo());
		System.out.println(feifei.getInfo());
		
		System.out.println(beibei.country);
		System.out.println(yunchang.country);
		System.out.println(feifei.country);
		
		beibei.country = "秦国";
		System.out.println("--------------------------");
		System.out.println(beibei.country);
		System.out.println(yunchang.country);
		System.out.println(feifei.country);
		
		System.out.println("--------------------------");
		
		System.out.println(Role.country);//用类名调用静态变量
	}
}
//		角色
class Role{
	private String name ;
	 static String country = "蜀国";//静态变量(全局变量)
	public Role(String name,String country){
		this.name = name;
		this.country = country;
		
	}
	public Role(String name){
		this.name = name;
		
	}
	public void setName(String name){
		
		this.name = name;
	}
	public String getName(){
		
		return name;
	}
	//静态方法只能访问静态的数据
	public static void setCountry(String country){
		
		Role.country = country;
	}
	/**
	public void setCountry(String country){
		
		this.country = country;
	}
	public String getCountry(){
		
		return country;
	}
	*/
	public String getInfo(){
		return "name:"+name+",country:"+country;
	}
}

声明为static的方法有一下几条限制:

        它们仅能调用其他的static方法。

        它们只能访问static数据。

        它们不能以任何方式引用this或super。

什么时候使用static?

所有对象共用属性或方法,那么我们应该定义为静态的。

11.main方法分析

主方法:

public static void main(String[]args){
    //代码块
}

public:公有的,最大的访问权限

static:静态的,无需创建对象

void:表示没有返回值,无需向JVM返回结果

main:方法名,固定的方法名

String[]args:表示参数为字符串数组,可以在调用方法时传入参数

12.代码块

1.普通代码块

直接写在方法中的代码块就是普通代码块

示例:

public class Test7{
	
	public static void main(String[]args){
	
	}
}

class Student{
	
	public void study(){
		//限制作用域,生命周期就在括号里
		
		{
			int i = 20;
			
			System.out.println(i);
		}
		
		
	}
}

2.构造块是在类中定义的代码块

示例:

/** 
	代码块:
	1.普通代码块,在方法中写的代码块
	2.构造块是在类中定义的代码块,在创建对象时被调用,优于构造方法执行
*/

public class Test7{
	
	public static void main(String[]args){
	
	Student s = new Student();
	Student s2 = new Student();
	Student s3 = new Student();
	}
}

class Student{
	
	
	public Student(){
		
		System.out.println("构造方法");
	}
	{
		
		System.out.println("我是构造代码块");
	}
	public void study(){
		//限制作用域,生命周期就在括号里
		
		{
			int i = 20;
			
			System.out.println("我是普通代码块");
		}
		
		
	}
}

3.在类中使用static声明的代码块成为静态代码块

示例:

/** 
	代码块:
	1.普通代码块,在方法中写的代码块
	2.构造块是在类中定义的代码块,在创建对象时被调用,优于构造方法执行
	3.在类中使用static声明的代码块成为静态代码块
		在第一次使用的时候被调用(创建对象),只会执行一次,优于构造块执行
		执行顺序:静态代码块>构造块>构造方法
		我们在项目开发中,通常会使用静态代码块来初始化只调用一次的数据.比如说:
*/

public class Test7{
	
	public static void main(String[]args){
	
	Student s = new Student();
	Student s2 = new Student();
	Student s3 = new Student();
	}
}

class Student{
	
	
	
	public Student(){
		
		System.out.println("构造方法");
	}
	{
		
		System.out.println("我是构造代码块");
	}
	static {
		
		System.out.println("我是静态代码块");
	}
	public void study(){
		//限制作用域,生命周期就在括号里
		
		{
			int i = 20;
			
			System.out.println("我是普通代码块");
		}
		
		
	}
}

4.同步代码块(多线程中讲解)

13.单例设计模式

单例设计模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点。

1.构造方法私有化

2.声明一个本类对象

3.给外部提供一个静态方法获取对象实例

两种实现方法:

1.饿汉式

2.懒汉式

/** 
	1.构造方法私有化

	2.声明一个本类对象

	3.给外部提供一个静态方法获取对象实例
	
	1.饿汉式:在类被加载后,对象被创建,到程序结束后释放
	2.懒汉式:在第一次调用getInstance方法时,对象被创建,到程序结束后释放
*/
public class Test8{
	
	public static void main(String[]args){
		
		//私有化不能new
		//Singleton1 s = new Singleton1();
		
		Singleton2 s = Singleton2.getInstance();
		s.print();
		Singleton2 s2 = Singleton2.getInstance();
		s2.print();
		
		System.out.println(s==s2);
	}
}

//饿汉式:占用内存的时间长,提高效率
class Singleton1{
	
	private Singleton1(){}//私有构造
	private static Singleton1 s = new Singleton1();
	public static Singleton1 getInstance(){
		return s;
	}
	public void print(){
		
		System.out.println("测试方法");
	}
}

//懒汉式:占用内存的时间短,效率低(懒加载,延迟加载)
//在多线程访问时会有安全问题
class Singleton2{
	
	private Singleton2(){};//私有构造
	private static Singleton2 s;
	
	public static Singleton2 getInstance(){
		if(s==null){
			s = new Singleton2();
		}
		return s;
	}
	public void print(){
		
		System.out.println("测试方法2");
	}
}

14.对象数组与管理

1.对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋给数组。

示例:

/** 
	对象数组与管理
	使用对象数组实现多个Chicken的管理
	动态数组:
	1.数组是一种线性数据结构
	2.数组不适合做删除插入等操作,适合添加,查找,遍历
*/

import java.util.Arrays;

public class Test9{
	
	public static void main(String[]args){
		ChickenManager cm  = new ChickenManager(5);
		//添加
		cm.add(new Chicken(1,"小小",10));
		cm.add(new Chicken(2,"小二",8));
		cm.add(new Chicken(3,"小三",6));
		cm.add(new Chicken(4,"小红",4));
		cm.add(new Chicken(5,"小奋",2));
		
		cm.add(new Chicken(6,"小斗",1));
		System.out.println("数组的长度是:"+cm.length());
		System.out.println("-------------printAll-------------");
		cm.printAll();
		System.out.println("-------------find-------------");
		
		Chicken c = cm.find(6);
		
		c.print();
		
		System.out.println("-------------update-------------");
		cm.update(new Chicken(2,"小小鸡",20));
		cm.printAll();
	}
	
}
//小鸡管理类
class ChickenManager{
	
	private Chicken[] cs = null;
	private int count = 0;//纪录当前数组的元素个数(下标)
											// 大小
	public ChickenManager(int size){
		if(size>0){
			cs = new Chicken[size];
		}else{
			cs = new Chicken[5];
		}
	}
	
	public int length(){
		return cs.length;
	}
	
	//添加:实现动态数组
	public void add(Chicken c){
		if (count>=cs.length){//数组已满,需要扩充
			
			//算法一:扩充原来数组大小的一半 cs.length*3/2+1
			//算法二:扩充原来数组的一倍	cs.length*2
			int newLen = cs.length*2;
			cs = Arrays.copyOf(cs,newLen);
			
			
		}
			cs[count] = c;
			count++;
	}
	public void delete(int id){
		for(int i = 0;i<count;i++){
			if(cs[i].getId()==id){
				//找到了要删除的对象,把该对象之后的对象向前移动一位
				for(int j = i;j<count-1;j++){
					cs[j] = cs[j+1];
					
				}
				//把最后一个对象赋值为空(删除)
				cs[count-1] = null;
				count--;//下标减一
				break;
			}
		}
	}//删除
	public void update(Chicken c){
		Chicken temp = find(c.getId());
		if(temp!=null){
			temp.setName(c.getName());
			temp.setAge(c.getAge());
		}
	}//更新
	public  Chicken find(int id){//查找
	
		for(int i = 0;i<count;i++){
			if(cs[i].getId()==id){
				return cs[i];
			}
		}
	
		return null;
		}
	public void printAll(){
		for(int i = 0;i<count;i++){
			cs[i].print();
		}
	} //输出所有
}
//小鸡类(数据对象) valueobject(VO)
class Chicken{
	
	private int id;
	private String name;
	private int age;
	public Chicken(){}//一般情况下最好保留默认的构造方法
	public Chicken(int id,String name,int age){
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public void setId(int id){
		this.id = id;
	}
	public int getId(){
		return id;
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return age;
	}
	public void print(){
		System.out.println("id="+id+",name="+name+",age="+age);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值