JavaSE面向对象

面向对象概述

(1)面向对象是一种自下而上的程序设计方法,一数据为中心,类是表现数据的单位,是划分程序的基本单位
(2)面向对象设计师自下而上的特性,允许开发者从问题的局部开始,在开发过程中逐步加深对系统的理解,需求变化会作用到系统开发本身,形成一种螺旋式的开发方式
(3)面向对象设计中,类封装了数据,而类的成员函数作为对外的接口,抽象地描述类,用类将数据和操作这些数据的函数放在一起,这就是面向对象设计方法的本质。

面向对象程序设计概述

  • 面向对象程序设计(object-oriented-programming,OOP)是放进主流的程序设计范型,它取代了20世纪70年代的“结构化”或者过程式编程技术。由于Java是面向对象的,所以必须熟悉OOP才能够很好的使用Java。
  • 面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐蔽的实现部分。程序中的很多对象来自标准库,还有一些是自定义的。究竟是自己构造对象,还是从外界购买对象完全取决于开发项目的预算和时间。

用Java语言对现实生活中的事物进行描述,通过类的形式来体现。

  • 类是具有共同属性和行为的对象的抽象,具有相同特性(数据元素)和行为(功能)的对象的抽象就是类
  • 对象的抽象就是类,类的具体化就是对象(对象是类的实例化)
  • 类实际上就是一种数据类型
  • 类是用于组合各个对象所共有操作和属性的一种机制
  • 类是具有相同属性和行为的一组对象的集合(1.类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。2.类具有操作,它是对象的行为的抽象,用操作名和实现操作方法来描述)
  • 类一旦定义后,就可以使用这个类来创建对应的对象(类就是对象的模板)
对象

对象是要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,他不仅能表示具体的事物,还能抽象规则、计划或事件。对象是一个客观存在的、唯一的实体,是一个类的工台实例化,拥有自己的表示、数据和行为。

对象的三个特性:

  • 对象的状态:每个对象都保存着描述当前状况的信息。调用哪些方法时对象会如何相应?
  • 对象的行为:可以对对象完成哪些操作,或者可以对对象应用哪些方法?
  • 对象的标识:如何区分具有相同行为与状态的不同对象?
面向对象的三大特征

1 封装


在面向对象程序设计方法中,封装(Encapsulation)是指一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法。

  • 封装被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随意访问
  • 需要访问该类的代码和数据,必须通过严格的接口控制。
  • 封装最主要的功能在于能修改自己的实现代码,而不用修改哪些调用代码的程序片段。
  • 释放的封装可以让程序代码更容易理解和维护,也加强了程序代码的安全性。
public class Student {
    //成员属性---静态特性的描述
    public boolean sex;//一般使用私有属性,可以使用get/set方法调用私有属性
    //成员方法---提供功能描述
    public boolean getSex(){
    	return this.sex;
    }
    //不允许修改sex,所以不提供set方法
    protected void setSex(boolean sex){
    	//如果在特殊情况下允许修改,可以使用范围限定词进行表示
    	this.sex = sex;
    }
}

//构建对象
Student stu = new Student();
stu.setSex(true);
stu.setSex(false);//是否允许取决于限制

封装的好处:

  1. 良好的封装能够减少耦合
  2. 类内部的结构可以自由修改
  3. 可以对成员进行更精确的控制
  4. 隐藏信息,实现细节

2 继承

继承就是子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法,或者子类从父类继承方法,使得子类具有父类相同的行为。
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据域或新的功能也可以用父类的功能,但不能选择性地继承父类。

继承的优点

  • 将所有子类的共同属性放入父类,实现代码共享,避免重复,提高开发效率
  • 可以使得修改扩展继承而来的实现比较简单

继承的缺陷

  • 父类变,子类就必须变
  • 继承破坏了封装,对于父类而言,它的实现细节对于子类来说都是透明的
  • 继承是一种强耦合关系

特殊关键字

Package

包是类或接口的容器,是一个用于避免命名冲突的名空间,是一个逻辑命名的概念,与具体的物理位置无关,在具体的实现中,包名称经常和目录名称对应

  • 包是类的组织方式,提供名空间和访问控制
  • 类似于文件系统的组织

声明包中的类package
语法:package 包名称;

  • 声明包要求是源代码文件的第一个语句。包定义之前可以添加注释信息
  • 程序中最多只能有一条package语句,没有包定义的源代码文件成为默认包中的一部分
public class A1{
	public void cc(){
		System.out.println("Hello World!");
	}
}
  • 程序中如果有package语句,该语句必须是第一条语句(前边只能有注释或者空行)

包的使用

import java.util.Date;

//用法1
public class A{
	public static void main(String[] args{
		Date now = new Date();//使用类的简称而不是全程java.util.Date
	}
}


//用法2
java.util.Date now = new java.util.Date();//不需要进行导包语句

///

//引入包import
System.out.println("显示输出");//不需要import java.lang.System

//同包中的其他类不需要导入
package com.sxn;
public class A{};

package com.sxn;
public class B{
	public void pp(){
		A a = new A();//不需要import com.sxn.A;
	}
}

  1. 引入包中的类:import包名称.类名称;例如import java.util.Date;
  2. 引入整个包:import 包名称.*;例如import java.util.*;
  3. 不引入包而是用类,则需要用累的全名:包名.类名,例如java.util.Date d = new java.util.Date();

范围限定词和包

//定义不包含在其他类中的外部类时,class前的范围限定词可以使用public或者默认
//public到处可见,没有限定词只能同包可以访问

package com.sxn.test1;//test1包
public class A{

	public static void main(String[] args{
		B b = new B();
	}
}
class B{}

//
package com.sxn.test2;//test2包
public class C{
	public static void main(String[] args){
		B b = new B();//语法报错,B类是默认限定词,则只能在com.sxn.test1;包中进行访问
	}
}

//成员属性和成员方法:定义在class内部,除了构造器(匿名内部代码块)和构造器之外的其他内容
public class A{
	public A(){}//构造器:方法名和类名一致,而且没有返回值
	public int A(){return;}//语法正确,但是不是构造器,可以直接调用,new A().A();

	//成员方法
	//public范围限定词 返回数据类型 方法名称(参数类型1 形参名称1,...){//若函数没有返回值,这函数返回数据类型为void
	//	return ;
	//}
	//调用成员方法的方式:对象名.方法名称(实际参数列表)
}

Java常用的包

  1. java.applet: 用于提供Applet开发的支持,目前已经被flash替代,很少使用,只有在某些地图系统中仍然使用
  2. java.swt和javax.swing: 用于单机软件或者C/S应用中的界面开发
  3. java.io: 用于输入、输出操作
  4. java.lang: 语言包,默认自动加载
  5. java.net: 用于网络编程
  6. java.util: 工具包,为Java提供一些工具类
面向对象基础练习

面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。在面型对象程序设计中,不必关心对象的具体实现,在传统的结构化程序设计中,算法是第一位的,数据结构是第二位,即首先确定如何操作,再考虑如何组织数据,以方便操作。而面向对象则颠倒了次序,将数据结构放在第一位,然后再考虑操作数据的算法。
抽象
忽略一个对象或实体的细节而只关注器本质特征的过程,可以简化功能与格式,帮助用户与对象交互是人类解决问题的基本方法。良好的抽象策略可以控制问题的复杂程度,增强系统的通用性和扩展性。

  • 过程抽象:将问题域中具有明确功能定义的操作抽取出来,并将其作为一个实体来看待
  • 数据抽象:将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟

    类是床架对象的模板和蓝图。由类构造对象的过程称为创建对象的实例
    设计与编写类的过程实际上是一个对实体共有属性和行为的一个抽象的过程
    eg:
class Student {
	private Long id;//如果使用包装类,则默认值为null
	private String username = "shenxioanan";
	private int age;//如果使用简单类型,则数值型默认为0,布尔型为false
	public void study(){}
	public void sleep(){}
}
//测试
public class Test{
	public static void main(String[] args){
		Student stu = new Student();
		stu.方法名();//调用成员方法
	}
}

字段和方法
定义 一个类时,可以在类里设置两种类型的元素:数据成员和成员函数。其中数据成员是一种对象,可以是任何类型,如果是指向对象的句柄,则必须初始化,这个句柄。通过构造器与一个实际对象连接起来,如果是基本数据类型,则可以在类定义的位置直接初始化。

public class Stuent{
	private int age;
	private String username;
	private Course[] course;
}
class Course{}

每个对象都有自己的数据成员存储空间,数据成员不会在每个对象之间共享的

Student s1 = new Student();
Student s2 = new Student();
s1.setName("sxn");
Syste,.out.println(s2.getName());

指针和引用的区别:

指针是一个存放地址的变量,是程序员可以灵活的访问内存,由于可以对指针进行任意的运算操作,所以也给程序员带来了安全隐患和意想不到的记过。引用也叫句柄,类似于指针,但是和指针不同。引用继承了指针节省内存的优点,但是限制了对地址的操作,它是安全的。Java中所有的变量都是一个引用,Java中没有指针的概念。

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

class Student{
	private String username;//成员变量属性-->字段(定义在所有方法之外,在整个类体内部范围内,和具体的定义位置无关)

局部变量定义在方法、语句、局部代码块中,只在所属的区域中有效,而且必须是先定义再赋值后使用。

public static void pp(){
	int num  = 100;//局部变量
	for (int k = 0;k<10;k++){}//局部变量
}

成员变量:
存在于对内存的对象中,堆内存中的对象大小可以是任意的,并允许运行时进行调整。所以访问查找的效率比较低。成员变量随着对象的创建而存在的,随对象的消失而消失。成员变量都有默认的初始值。
局部变量:
存在于栈内存的方法中,可以快速定位,但是大小是限定的。局部变量随着所属区域的执行而存在,随着所属区域的结束而释放,局部变量没有默认初始化值。

用引用(句柄)操作对象
调用形式为对象名.方法名

方法
方法可以理解为一个命名的代码块,通过名称就可以重复使用这段代码,而不需要重复书写,提高代码的复用性。

//参数:指进入方法中的数据,有了这些数据,方法才能执行逻辑
//返回值:指从方法中出来的数据,也就是方法执行之后的最终结果数据
//方法可以有参数、也可以没有参数、方法可以有返回值、也可以没有返回值
//基本格式:
修饰符 返回值类型 方法名称(参数类型 参数名称){
	方法体;
	return 返回值;
}
  • 返回值类型:方法最终产生的结果数据是什么类型(返回值必须和返回值类型对应);
  • 方法名称:自定义的名称,命名规则和变量一样
  • 参数类型:进入方法的数据是什么类型(参数如果有多个,需要用逗号隔开,如果没有参数可以留空);
  • 方法体:方法内部执行的若干行代码(多个方法的定义先后顺序无所谓,不能在一个方法内部定义方法);
  • return:结束方法的执行,并且将返回值还给调用处;
  • 返回值:方法最终产生的结果数据。

参数传递

  1. 形式参数:在定义方法的时候,写子啊小括号之内的变量,就叫形式参数,实际上在方法定义中起到占位符的作用,会在方法调用是被传递过来的实际之所替代(声明方法时圆括号中的参数—>形参列表);
  2. 实际参数:在调用方法的时候,真正传入方法里的数据,称为实际参数(圆括号中的实参列表为调用方法时时间传入的实际参数—>实参列表)

面向对象练习

  1. 猜数字游戏
public class GuessGame{
	private int target = 0;//猜测的目标值
	private int[] history = new int[15];
	private int count = 0;
	//产生随机数
	public GuessGame(){
		target = (int)(Math.random()*100);
	}
	//判断条件
	public boolean guess(int number){
		history[count++] = number;
		boolean res = false;
		if (number>target){
			System.out.println("你猜大了!");
		}else if (number<target){
			System.out.println("你猜小了!");
		}else{
			System.out.println("你猜小了!");
			res = true;
		}
		return res
	}
	//main方法
	public static void main(String[] args){
		GuessGame gg = new GuessGame();
		Scanner sc = new Scanner(Systemin);
		while(true){
			System.out.println("请输入你猜测的整数值:")
			int kk = sc.nextInt();
			boolean ret = gg.guess(kk);
			if(rst)
				break;
		}
		sc.close();
	}
}

2.计算圆的面积和周长,输入半径值

public class Circle{
	private double redius;//半径
	public Circle(double r){
		redius = r;	
	}
	public double getArea(){
		return Math.PI*redius*redius;	
	}
}
  1. 请定义一个交通工具Vehicle的类,其中有:
    属性:速度(speed),车的类型(type);
    方法:移动(move),设置速度(setSpeed),加速(speedUp),减速(speedDown),最后在测试类Vehicle中的main( )中实例化一个交通工具对象,并通过构造方法给它初始化speed,type的值,并且打印出来。另外,调用加速,减速的方法对速度进行改变。
class Vehicle{
	private int speed;
	peivate String type;
	//加速
	public void speedUp(double s){
		speed+=s;
	}
	//减速,并且判断速度减少至0不再减少
	public void speedDown(double s){
		speed-=s;
		if(speed <= 0)
			speed = 0;
	}
	//设置速度
	public void setSpeed(double s){
		speed = s;	
	}
}
  1. 利用继承来描述人、老师、学生之间的关系:
    (1)老师含有属性:name,age,subject;含有方法:eat,teach,toString。
    (2)学生含有属性:name,age,class;含有方法:eat,study,toString。
    (3)利用继承的思想,从老师和学生中抽象出人,并创建Test进行调用和输出。
class Teacher{
	private String name;
	private int age;
	private String subject;
	public void eat(){
		System.out.prinln("教师正在吃饭!");
	}
	public void teach(){
		System.out.println("教师正在教书!");
	}
	public String toString(){
		return "姓名:"+name+"年龄:"+age;
	}
}
class Student extends Teacher{
	private String name;
	private int age;
	private int class;
	public void eat(){
		System.out.prinln("学生正在吃饭!");
	}
	public void study(){
		System.out.println("学生正在教书!");
	}
	public String toString(){
		return "姓名:"+name+"年龄:"+age;
	}
}
  1. 定义一个类Calculate1,实现加、减两种运算,然后编写一个派生类Calculate2,实现惩处两种算法。
public class calculate1{
	private double num1;
	private double num2;
	public double add(){
		return num1+num2;
	}
	public double sub(){
		return num1-num2;
	}
	public void setNum1(double num1){
		this.num1 = num1;
	}
	public double getNum1(){
	return num1;
	}
	public void setNum2(double num2){
		this.num2 = num2;
	}
	public double getNum2(){
		return num2;
	}
}

public class Calculate2 extends Calculate1{
	public boolean mulltiple(){
		return this.getNum1()*this.getNUm2();
	}
}	

构造器

构造函数是一种特殊的方法,不是成员方法,主要作用是在创建对象时初始化对象,即为对象成员变量赋初始值,经常与new运算符一起使用在创建对象的语句中。

public class A{
	public A(){}//不允许有返回值类型
	public A(int k){}//重载构造函数
	public A(String name){}//参数个数不同、参数类型不同
	public A(int k,String name){}
}
//创建对象
new A(); //对应的构造器为A(){}
new A(100); //对应的构造器A(int k){}
new A("shenxiaonan"); //对应的构造器A(String name){}

构造器特点

  • 函数名与类名相同
  • 不用定义返回值类型
  • 没具体的返回值
  • 一个类可以有多个不同的构造器,但是参数一定不能相同(参数名不做限制)
  • 若给构造函数加上返回值则成为了成员方法

构造器的作用

public class Student{
	private String name;
	private int age;
	//this.name表示成员变量,直接使用name表示局部变量
	public Student(String name,int age){
		this.name = name;
		this.age = age;
		System.out.println(name);//不加this.则使用的是局部变量
	}
}

构造方法的调用
当使用new运算符时构造函数自动进行调用,不需要人为进行调用

  • 关键字new通常称为穿点运算符,用于分配对象内存,并将该内存初始化为缺省值
  • 如果new完成分配和初始化内存,他就调用构造函数执行对象初始化
  • 创建对象都必须通过构造函数初始化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值