类和对象2

1回顾

1.1面向对象和面向过程

面向对象:面对一个问题(老曹开车去重庆),考虑需要多少对象,在考虑每个对象有哪些方法(行为)和属性(特征),最后考虑对象之间如何协作

面向过程:面对一个问题,考虑分步骤去解决,不去考虑对象的存在。

面向过程用于开发简单的程序

汇编、C语言为代表

手机卡充值、电脑的驱动

面向过程不会被淘汰。

面向对象用于企业软件开发,通常用于复杂的业务逻辑

1.2定义类

1.3创建对象

1.4调用方法

//作业:定义一个学生类型 name  no  age     eat()  study()
package com.whsxt.day2.homework;

public class Student {
	String name;
	
	/**
	 * 学号
	 */
	String no;
	
	public void eat(){
		System.out.println(name+"吃饭.....");
	}
	
	public void study(){
		//先吃饭再学习,在study()方法里面调用eat()方法
		eat();
		System.out.println(name+"正在学习,学号是:"+no);
	}
}


package com.whsxt.day2.homework;

/**
 * @author caojie
 * 在学校可以创建学生
 * 学校有学生
 */
public class School {
	public static void main(String[] args) {
		//new Student() 表示创建了一个Student类型的对象
		// tom 接收创建的对象  tom理解为Student类型对象的代言人
		// tom操作Student类型的对象
		Student tom = new Student();
		tom.name="Tom";
		tom.no="FK01243224";
		tom.study();
	}
}

2类和对象

2.1构造方法

2.1.1概念

使用new关键字调用的方法叫做构造方法,通常在工作中用于创建对象

例如: new Scanner(System.in);  //创建扫描器对象

	    new Student();  创建学生对象

Student tom = new Student();

2.1.2特征

1 构造方法的名称必须跟类同名

2 构造方法没有返回值

3  如果一个类没有定义构造方法,那么在执行过程中,JVM会为其分配一个默认构造方法	 

2.1.3作用

唯一的职责:创建对象,为对象的属性赋值(为对象的属性初始化)

2.1.4解决哪些问题

使用构造方法完成属性的赋值(初始化)

package com.whsxt.day2.oop1;

public class Student {
	
	String name;
	
	int age;
	
	String no;
	
	/**
	 * 爱好
	 */
	String hobby;
	
	/**
	 定义构造方法,在构造方法体内部为属性赋值
	 将局部变量的值赋给成员变量
	 例如: 局部变量stuName的值赋给成员变量name
	 */
	Student(String stuName,int stuAge,String stuNo,String stuHobby){
		name = stuName;
		age = stuAge;
		no = stuNo;
		hobby = stuHobby;
	}

	public void study(){
		//成员方法执行的时候,所有的属性都被构造方法初始化了(赋初始值)
		System.out.println(name+"正在学习,学号是:"+no+"年龄是:"+age);
		System.out.println("学习完毕"+hobby);
	}
}


package com.whsxt.day2.oop1;

public class School {
	public static void main(String[] args) {
		//Student tom = new Student();
		//直接为属性赋值存在确定:赋值麻烦,容易出现漏写
		//如何解决:将属性赋值的过程交给构造方法来完成
//		tom.age=18;
//		tom.hobby="Football";
//		tom.no="AF10011";
//		tom.study();
        //调用构造方法创建对象
		Student tomson = new Student("Tomson", 18, "AF010101", "Football");
        //调用成员方法
		tomson.study();
	}
}

小结:1构造方法用于确保对象属性的完整性(初始化对象的属性)

	    2 此时成员方法调用之前所有的属性都会妥善初始化

2.2this关键字

概念:this表示当前使用new关键字创建的对象

工作中那些地方会用到this关键字:

1当成员变量(属性)和局部变量(参数)名称相同,使用this区分

package com.whsxt.day2.oop2;

public class Student {
	String stuName;
	int stuAge;
	String stuNo;
	String stuHobby;
	
	/**
	 定义构造方法,在构造方法体内部为属性赋值
	 将局部变量的值赋给成员变量
	 例如: 局部变量stuName的值赋给成员变量name
	 */
	Student(String stuName,int stuAge,String stuNo,String stuHobby){
		//局部变量的值赋给局部变量(自己)
		//stuName = stuName;
		//此时this.stuName表示当前对象的成员变量(stuName)
		this.stuName = stuName;
		this.stuAge = stuAge;
		this.stuNo = stuNo;
		this.stuHobby=stuHobby;
	}

	public void study(){
		//String stuHobby="Basketball";
		//成员方法执行的时候,所有的属性都被构造方法初始化了(赋初始值)
		System.out.println(stuName+"正在学习,学号是:"+stuNo+"年龄是:"+stuAge);
		System.out.println("学习完毕"+this.stuHobby);
	}
}

2 一个构造方法里面调用另外一个构造方法

package com.whsxt.day2.oop2;

public class Student {
	String stuName;
	int stuAge;
	String stuNo;
	String stuHobby;
	
	/**
	 定义构造方法,在构造方法体内部为属性赋值
	 将局部变量的值赋给成员变量
	 例如: 局部变量stuName的值赋给成员变量name
	 */
	Student(String stuName,int stuAge,String stuNo,String stuHobby){
		this.stuName = stuName;
		this.stuAge = stuAge;
		this.stuNo = stuNo;
		this.stuHobby=stuHobby;
	}
	Student(){
		//在无参构造方法中调用有参构造方法 默认的名称、年龄、学号、爱好
        //编译错误:一个构造方法调用另一个构造方法必须位于第一行
        //System.out.println("Start");
        //一个构造方法调用另一个构造方法的操作只能一次
        //this("Jerry");
		this("Stone", 20, "ABCDEFG", "Swimming");
	}
	Student(String stuName){
		
	}
	public void study(){
		//String stuHobby="Basketball";
		//成员方法执行的时候,所有的属性都被构造方法初始化了(赋初始值)
		System.out.println(stuName+"正在学习,学号是:"+stuNo+"年龄是:"+stuAge);
		System.out.println("学习完毕"+this.stuHobby);
	}
}


package com.whsxt.day2.oop2;

public class School {
	public static void main(String[] args) {
		//使用无参数构造方法创建对象
		Student tomson = new Student();
		tomson.study();
	}
}

小结:如果一个类没有构造方法,会分配一个默认无参构造方法,如果有构造方法,再也不会分配默认构造方法了

3面向对象特征之封装

封装、继承、多态

Java为什么是面向对象的语言?因为Java支持面向对象的特征封装、继承、多态,所以是面向对象语言。

封装的概念:如果你不想让某些数据被外界访问,那么将数据隐藏

		  如果你想让某些数据对外公开,可以将数据公开。

3.1属性的封装

为什么需要对属性进行封装?

直接为属性赋值,缺点是不可控,因为:你无法判断属性的名称是否为空,无法判断邮箱是否合法。

如何为属性进行封装呢?

将属性私有化,然后为属性提供setXXX方法和getXXX方法,通过调用setXXX方法为属性赋值,调用getXXX()方法获取(读取)属性的值。

好处:你在调用setXXX方法为属性赋值之前可以验证有效性,从而可以控制属性赋值的正确性。

如何操作?

package com.whsxt.day2.oop3;

public class Student {
	
	/**
	 *封装 属性私有化,外界不能直接访问我的私有属性
	 */
	 private String name;
	
	/**
	 * 为属性赋值
	 * @param name 学生姓名
	 */
	public void setName(String name){
		//条件成立:表示参数name为空,为其产生一个默认名称
		if(null == name || name.length()==0){
			this.name="Stone";
		}else{
			this.name = name;
		}
	}
	
	public String getName(){
		return name;
	}
	
	public void study(){
		System.out.println(name+"正在学习");
	}
}

package com.whsxt.day2.oop3;

public class School {
	public static void main(String[] args) {
		Student stu = new Student();
		//stu.name ="Tom";
		//stu.name= null;
		//为属性赋值
		stu.setName(null);
		//调用Student对象的getName()方法获取名称
		String stuName = stu.getName();
		System.out.println("stuName="+stuName);
        //编译错误:The field Student.name is not visible
		//name属性不能访问(不是有效的)
		//stu.name="Sam";
	}
}

小结:属性封装的核心private关键字

   private私有化, 请不要碰我(除了定义属性的类本身,其它任何地方都不能访问)

   属性私有化,但是可以提供setXXX()方法设置属性的值,set开头的方法是变异器(值可以改变的),例如name=null;------------》name="Stone"

			  该可以提供getXXX()方法访问属性值,get开头的方法访问器(外界调用get方法获取属性值)

setXXX():写操作 (改变属性值)

getXXX():读操作(获取属性值)

作业:定义动物类,属性和行为自己定义

1 练习构造方法

2 练习this关键字

3 练习封装

3.2方法的封装

隐藏实现细节

    场景:输入一个年份,判断是否是闰年

特征:输入一个数字,得到一个结果。如何判断闰年,我向外界隐藏

package com.whsxt.day2.oop4;

/**
 * @author caojie
 * 方法的封装
 * Leap有一个方法judgeLeap()用来判断某个年份是否为闰年,判断的细节对外界隐藏
 * 只提供方法给外界调用(隐藏了实现细节)
 */
public class Leap {
	private int year;
	public void setYear(int year){
		this.year = year;
	}
	public int getYear(){
		return year;
	}
	public Leap(int year){
		this.year = year;
	}
	/**
	 * 判断年份是否为闰年
	 * @return true 是闰年,false不是闰年
	 */
	public boolean judgeLeap(){
		return year%4==0 && year%100!=0 || year%400==0;
	}
}


package com.whsxt.day2.oop4;

import java.util.Scanner;

/**
 * @author caojie
 * 验证方法的封装
 * 客户使用Leap类型完成闰年的验证
 */
public class Test {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("请输入年份");
		int year = input.nextInt();
		Leap leap = new Leap(year);
		//判断闰年的细节(如何判断),向客户隐藏
		boolean result = leap.judgeLeap();
		String rs = result?"闰年":"不是闰年";
		System.out.println(year+rs);
	}
}

3.3类的封装

具有相同属性(特征)和行为的一组对象,将其封装成一个类

场景:定义一个动物类,属性和行为自定义

package com.whsxt.day2.oop5;

/**
 * @author caojie
 * 具有相同属性(特征)和行为的一组对象,将其封装成一个类
 * 例如:小黑、小白、小花 都是Animal
 * 所有的动物都有 昵称
 * 所有的动物都有 吃饭的行为
 */
public class Animal {

	/**
	 * 动物的昵称
	 * Alt+S --->Generic Getters/Setters 自动生成Get/Set
	 */
	private String nikeName;

	public String getNikeName() {
		return nikeName;
	}

	public void setNikeName(String nikeName) {
		this.nikeName = nikeName;
	}

	public Animal(String nikeName) {
		this.nikeName = nikeName;
	}

	public Animal() {
		this("小黑");
	}
	
	/**
	 * 所有的动物都具备吃饭的行为
	 * @param food  食物  
	 */
	public void eat(String food){
		System.out.println(nikeName+"正在吃"+food);
	}
}


package com.whsxt.day2.oop5;

/**
 * @author caojie
 *动物园管理员:产生一个或者一组对象
 */
public class Zookeeper {
	public static void main(String[] args) {
		Animal xiaoHei = new Animal();
		xiaoHei.eat("骨头");
	}
}

3.4构造方法的封装

如果你想让构造方法给外界使用,将其定义为公有

如果你不想让构造方法给外界使用,其定义为私有

如果你只想让构造方法在包的内部使用,将其定义为friendly (什么都不写) 

	Student(){}

package com.whsxt.day2.oop6;

public class Danta {

	private String color;
	
	/**
	 * 公有化的构造方法,任何地方都能访问,本类、同一包下、包外部都可以访问(创建对象)
	 * @param color
	 */
//	public Danta(String color){
//		this.color = color;
//	}
	/**
	 * 没有任何访问修饰符是friendly,只能在本类和包内部
	 */
//    Danta(String color){
//		this.color = color;
//	}
	/**
	 * 构造方法私有化,自己可以访问自己:除了本类其它任何地方都不能访问
	 */
	private static Danta danta = new Danta("Yellow");
	
    private Danta(String color){
		this.color = color;
	}
    
    /**
     * 定义一个公有的静态的方法,返回唯一Danta对象
     */
    public static Danta getDanta(){
    	return danta;
    }
}

package com.whsxt.day2.oop7;

import com.whsxt.day2.oop6.Danta;

public class KFC2 {
	public static void main(String[] args) {
		//在包外也可以创建Danta对象
		//不能再包外部访问friendly构造方法
		//new Danta("Yellow");
		//调用Danta的公有的静态的方法,获取Danta对象
		Danta danta = Danta.getDanta();
		System.out.println(danta);
	}
}

小结:1和对象之间的联系?

   类是对象的一个抽象表示,一个类可以创建多个对象

   对象是类(Type  or  Class)的一个实例,  猫、狗都是动物类型的一个实例

  2封装:隐藏数据	   

		private  除了类本身,其它任何地方都不能访问

		public    任何地方都能访问

 3对象之间的一个关系

	学生有车

package com.whsxt.day2.oop8;

public class Car {
	
	/**
	 * 车有品牌
	 */
	private String brand;

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public Car() {
	}

	public Car(String brand) {
		this.brand = brand;
	}
	
	public void start(){
		System.out.println(brand+"启动");
	}
	
	public void stop(){
		System.out.println(brand+"停车");
	}
	
	public void speed(){
		System.out.println(brand+"加速");
	}
}


package com.whsxt.day2.oop8;

public class Student {

	private String name;
	
	/**
	 * 学生有车
	 */
	private Car car;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Car getCar() {
		return car;
	}

	public void setCar(Car car) {
		this.car = car;
	}

	public Student(String name, Car car) {
		this.name = name;
		this.car = car;
	}

	public Student() {
	}
	
	public void driver(){
		//有车对象才能驾驶
		if(null != car){
			car.start();
			car.speed();
			car.stop();
		}else{
			System.out.println(name+"不具备驾驶行为");
		}
	}
}


package com.whsxt.day2.oop8;

public class School {
	public static void main(String[] args) {
		//创建一个车对象:benz
		Car benz = new Car("Benz");
		//创建学生对象  将Car对象benz注入到Student中
		Student sam = new Student("Tom", benz);
		sam.driver();
	}
}

作业:练习对象之间的关系

    房子有窗户

    电脑有鼠标

4面向对象特征之继承

4.1生活中的继承

父和子的关系,父在上,子在下

4.2程序中的继承

继承的语法:

public 子类 extends 父类{

}

extends: 扩展、延伸(子类是父类的一个延伸)

子类可以使用父类的非私有属性和行为

场景:学生是人

人是父类:有eat()方法

学生是子类:有name属性,有eat()方法和study()方法

package com.whsxt.day2.oop9;

/**
 * @author caojie
 * Person 是一个父类,所有的Person都有吃饭的行为
 */
public class Person {
	public void eat(){
		System.out.println("吃饭");
	}
}


package com.whsxt.day2.oop9;

/**
 * @author caojie
 * 学生继承人类
 */
public class Student extends Person {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

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

	public Student() {
		
	}
	
	public void study(){
		System.out.print(name);
		//因为子类继承于父类,所以子类可以使用父类的非私有行为(方法)
		eat();
		System.out.println("study");
	}
}

测试类

package com.whsxt.day2.oop9;

public class School {
	public static void main(String[] args) {
		Student tom = new Student();
		tom.setName("Tom");
		tom.study();
	}
}

4.3super关键字

this当前对象

super当前对象的父对象

作业:人有姓名和年龄,会吃饭和走路

    学生是人有学号,能够学习

   动物有颜色、性别属性,会吃饭、会跑

    猫是一种动物,有昵称属性,会爬树

4.4继承中的构造方法

4.5访问权限

4.6方法覆盖

4.7final关键字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值