面向对象基础
-------
面向对象、类与对象的定义
面向对象概念
程序的发展经历了两个主要阶段:面向过程、面向对像
对于面向对象与面向过程可以用一个例子解释,如一个木匠要做一个盒子,那么做这个盒子的出发点会有两种方式:
·面向对象:先想好要做的盒子,之后再去找相应的工具去做。
·面向过程:不去想要做什么样的盒子,随需随取工具。
面向对象的三大特征
l 封装(Encapsulation) 对外部不可见。可以保护程序中的某些内容。
l 继承(Inheritance) 扩展类的功能
l 多态(Polymorphism) 方法重载 与 对象的多态性
类与对象的关系
面向对象的核心组成部分:类与对象。
类是对某一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每个个体,因而也称实例(instance)。
类就相当于是一个模板,依照此模板产生产品
利用class关键字来定义一个类
对象的创建及使用
类名 对象名称 = null; //声明对象
对象名称 = new 类名(); //实例化对象
类名 对象名称= new 类名();
内存划分
Person per = new Person();
声明对象:Person per,栈内存中声明的,与数组一样,数组名称就是保存在栈内存之中,只开辟了栈内存的对象是无法使用的,必须有其堆内存的引用才可以使用。
实例化对象:new Person(),在堆中开辟空间,所有的内容都是默认值。
String:是一个字符串,本身是一个类,就是一个引用数据类型,则此时默认值就是null
Int:是一个整数,本身是一个数,所以是基本数据类型,则此时的默认值就是0.
内存操作:为属性赋值
- Person per = new Person();
- per.name = “张三”; //为属性赋值
- per.age = 30 ;
- per.tell(); //调用类中的方法
注意点:在使用对象的时候,对象必须被实例化后才可以使用。
编写程序:
- class Person{
- String name ; // 声明姓名属性
- int age ; // 声明年龄属性
- public void tell(){ // 取得信息
- System.out.println("姓名:" + name + ",年龄:" + age) ;
- }
- }
- public class ClassDemo06{
- public static void main(String args[]){
- Person per1 = null ; // 声明per1对象
- Person per2 = null ; // 声明per2对象
- per1 = new Person() ; // 实例化per1对象
- per2 = new Person() ; // 实例化per2对象
- per1.name = "张三" ; // 设置per1中的name属性内容
- per1.age = 30 ; // 设置per1中的age属性内容
- per2.name = "李四" ;
- per2.age = 33 ; // 设置per2中的age属性内容
- per2 = per1 ; // 把per1的堆内存空间使用权给per2
- System.out.print("per1对象中的内容 --> ") ;
- per1.tell() ; // 调用类中的方法
- System.out.print("per2对象中的内容 --> ") ;
- per2.tell() ; // 调用类中的方法
- }
- }
封装性
封装性就是保护内容,保证某些属性或方法可以不被外部看见。
为属性封装:private 属性类型 属性名称;
为方法封装:private 方法返回值 方法名称(参数列表){}
方问封装的内容
因为这些属性肯定是要表示出一些实际意义,那么这些意义的内容肯定应该由外部设定,所以在JAVA中对于封装性的访问就给出一个原则。
被封装的属性如果需要方问,则需要写setter及getter方法完成。
程序:
- class Person{
- private String name ; // 声明姓名属性
- private int age ; // 声明年龄属性
- public void setName(String n){ // 设置姓名
- name = n ;
- }
- public void setAge(int a){ // 设置年龄
- if(a>=0&&a<=150){ // 加入验证
- age = a ;
- }
- }
- public String getName(){ // 取得姓名
- return name ;
- }
- public int getAge(){ // 取得年龄
- return age ;
- }
- public void tell(){
- System.out.println("姓名:" + this.getName() + ",年龄:" + this.getAge()) ;
- }
- }
- public class EncDemo05{
- public static void main(String arsgh[]){
- Person per = new Person() ; // 声明并实例化对象
- per.setName("张三") ; // 调用setter设置姓名
- per.setAge(-30) ; // 调用setter设置年龄
- per.tell() ; // 输出信息
- }
- }
构造方法与匿名对象
构造方法声明注意事项:
构造方法的名称必须与类名称一致
构造方法的声明处不能有任何返回值类型的声明
不能在构造方法中使用return返回一个值
在整个JAVA操作中,如果一个类中没有明确声明一个构造方法,则会自动生成一个无参构造方法。
构造方法的主要目的是为类中的属性初始化
构造方法重载与普通方法一样 利用参数的类型或个数不同来完成
匿名对象:没有名字,在JAVA中如果一个对只使用一次,则就可以将其定底为匿名对象。
实例学习:
- class Student{
- private String stuno ;
- private String name ;
- private float math ;
- private float english ;
- private float computer ;
- public Student(){}
- public Student(String s,String n,float m,float e,float c){
- this.setStuno(s) ;
- this.setName(n) ;
- this.setMath(m) ;
- this.setEnglish(e) ;
- this.setComputer(c) ;
- }
- public void setStuno(String s){
- stuno = s ;
- }
- public void setName(String n){
- name = n ;
- }
- public void setMath(float m){
- math = m ;
- }
- public void setEnglish(float e){
- english = e ;
- }
- public void setComputer(float c){
- computer = c ;
- }
- public String getStuno(){
- return stuno ;
- }
- public String getName(){
- return name ;
- }
- public float getMath(){
- return math ;
- }
- public float getEnglish(){
- return english ;
- }
- public float getComputer(){
- return computer ;
- }
- public float sum(){ // 求和操作
- return math + english + computer ;
- }
- public float avg(){ // 求平均值
- return this.sum() / 3 ;
- }
- public float max(){ // 求最高成绩
- float max = math ; // 数学是最高成绩
- max = max>computer?max:computer ;
- max = max>english?max:english ;
- return max ;
- }
- public float min(){ // 求最低成绩
- float min = math ; // 数学是最高成绩
- min = min<computer?min:computer ;
- min = min<english?min:english ;
- return min ;
- }
- }
- public class ExampleDemo01{
- public static void main(String args[]){
- Student stu = null ; // 声明对象
- stu = new Student("CSDN","曹文涛",95.0f,89.0f,96.0f) ;
- System.out.println("学生编号:" + stu.getStuno()) ;
- System.out.println("学生姓名:" + stu.getName()) ;
- System.out.println("数学成绩:" + stu.getMath()) ;
- System.out.println("英语成绩:" + stu.getEnglish()) ;
- System.out.println("最高分:" + stu.max()) ;
- System.out.println("最低分:" + stu.min()) ;
- }
- }
String类
实例化String类
直接赋值:String name = “Hello World!”;
通过关键字new:String name = new String(“Hello World!”);
String类的内容比较
一是利用“=”完成,比较的是地址值
二是利用“equals”完成,比较的是字符串的具内容,比较常用。
一个字符串 就是String类的一个匿名对象
字符串的内容一旦声明则不可改变
掌握String类的一些常用方法以及API的查询
引用传递及其应用
代码实例
- class Person{ // 定义Person类
- private String name ; // 姓名
- private int age ; // 年龄
- private Book book ; // 一个人有一本书
- public Person(String name,int age){
- this.setName(name) ;
- this.setAge(age) ;
- }
- public void setName(String n){
- name = n ;
- }
- public void setAge(int a){
- age = a ;
- }
- public String getName(){
- return name ;
- }
- public int getAge(){
- return age ;
- }
- public void setBook(Book b){
- book = b ;
- }
- public Book getBook(){
- return book ;
- }
- }
- class Book{ // 定义Book类
- private String title ; // 标题
- private float price ; // 价格
- private Person person ; // 一本书属于一个人
- public Book(String title,float price){
- this.setTitle(title) ;
- this.setPrice(price) ;
- }
- public void setTitle(String t){
- title = t ;
- }
- public void setPrice(float p){
- price = p ;
- }
- public String getTitle(){
- return title ;
- }
- public float getPrice(){
- return price ;
- }
- public void setPerson(Person p){
- person = p ;
- }
- public Person getPerson(){
- return person ;
- }
- }
- public class RefDemo05{
- public static void main(String arg[]){
- Person per = new Person("张三",30) ;
- Book bk = new Book("JAVA SE核心开发",90.0f) ;
- per.setBook(bk) ; // 设置两个对象间的关系,一个人有一本书
- bk.setPerson(per) ; // 设置两个对象间的关系,一本书属于一个人
- System.out.println("从人找到书 --> 姓名:" + per.getName()+";年龄:"
- + per.getAge() +";书名:" + per.getBook().getTitle() + ";价格:"
- + per.getBook().getPrice()) ; // 可以通过人找到书
- System.out.println("从书找到人 --> 书名:" + bk.getTitle() + ";价格:"
- + bk.getPrice() + ";姓名:" + bk.getPerson().getName() + ";年龄:"
- + bk.getPerson().getAge()) ; // 也可以通过书找到其所有人
- }
- }
this 关键字
this关建字的作用: 可以用this强调本类中的方法,表示类中的属性,调用本类的构造方法,this表示当前对象。
使用this()调用构造方法的语句只能放在构造方法的首行。
在使用this调用本类中其它构造的时候,至少有一个构造方法不是this调用的
可以使用this和引用传递进行两个对象是否相等的判断
static关键字
在JAVA中可以使用static声明属性或方法,声明后的属性或方法也称类方法,可以由类名直接调用。也称静态
JAVA中的内存区域:
栈内存:可以保存对象的名称
堆内存:保存每个对象的具体属性
全局数据区:保存static类型的属性
全局代码区:保存所有方法的定义
利用static可以统计一个类到底产生了多少个实例化对象;还可以为对象进行自动编名操作。
理解main方法
public static void main(String args[])
public:表示此方法可以被外部所调用
static:表示此方法可以由类名称直接调用
void:主方法是程序的起点,所以不需要任何返回值
main:系统规定好默认调用的方法名称,执行的时候,默认找到main方法名称
String args[]:表示的是运行时的参数 (参数传递的形式: java类名称 参数1 参数2…..)
代码块即用{}括起来的一段化码,根据位置不同,可分为四种:普通代码块、构造块、静态代码块、同步代码块。
构造方法私有化 类的封装性不光体现在对属性的封装上,实际上方法也是可以被封装的。
一个类的构造方法被私有化之后,只能从其类的内部取得实例化对象。
单态设计模式 所谓单态就是在入口处(构造方法)限制了对象的实例化操作。
单态设计模式的核心就是将类的构造方法私有化,之后在类的内部产生实例化对象关通过类的静态方法返回实例化对象的引用。
对象数组
对象数组就是指包含了一组相关的对象,数组一定要先开辟空间,但是因为其是引用数据类型,所以数组里面的每一个对象都是null值,则在使用的时候数组中的每一个对象必须分别进行实例化操作。
类 对象数组名称[] = new 类[数组长度];
数组格式:数据类型 数组名称[] = new 数据类型[长度];
内部类
在一个类的内部还存在另外一个类,则称为内部类
内部类可声明成public或privat。当内部类声明成pubilc或private时,对其访问的限制与成员变量和成员方法完全相同。
内部类的特点:
缺点:正常的一个类操作时,在类中最好只定义属性或方法,如果定义一个类的话,则肯定破坏了程序的一个结构。
优点:可以降低代码量和复杂程度,可以方便的访问外部类中的私有属性。
实例系统登陆
- class Check{ // 完成具体的验证操作
- public boolean validate(String name,String password){
- if(name.equals("lixinghua")&&password.equals("mldn")){ // 验证
- return true ;
- }else{
- return false ;
- }
- }
- }
- class Operate{ // 本类只是调用具体的验证的操作
- private String info[] ; // 定义一个数组属性,用于接收全部输入参数
- public Operate(String info[]){
- this.info = info ; // 通过构造方法取得全部的输入参数
- }
- public String login(){
- Check check = new Check() ; // 实例化Check对象,用于检查信息
- this.isExit() ; // 判断输入的参数是否正确
- String str = null ; // 用于返回信息
- String name = this.info[0] ;// 取出姓名
- String password = this.info[1] ; // 取出密码
- if(check.validate(name,password)){ // 登陆验证
- str = "欢迎" + name + "光临!" ;
- }else{
- str = "错误的用户名和密码!" ;
- }
- return str ;
- }
- public void isExit(){ // 判断参数个数,来决定是否退出程序
- if(this.info.length!=2){
- System.out.println("输入的参数不正确,系统退出!") ; // 给出一个正确的格式
- System.out.println("格式:java LoginDemo02 用户名 密码") ;
- System.exit(1) ; // 系统退出
- }
- }
- }
- public class LoginDemo02{
- public static void main(String args[]){
- Operate oper = new Operate(args) ; // 实例化操作类的对象
- System.out.println(oper.login()) ; // 取得验证之后的信息
- }
- }
单向链表
链表是在数据结构中经常见到的一种形式,JAVA中通过引用传递的方式进行实现。
如果要想实现链表,则要设计一个链表的节点类,在此类中必须有一个属性可以保存下一个节点的引用地址。
对节点进行增加数据、查找数据、删除数据操作。具体代码:
- class Link{ // 链表的完成类
- class Node{ // 保存每一个节点,此处为了方便直接定义成内部类
- private String data ; // 保存节点的内容
- private Node next ; // 保存下一个节点
- public Node(String data){
- this.data = data ; // 通过构造方法设置节点内容
- }
- public void add(Node newNode){ // 将节点加入到合适的位置
- if(this.next==null){ // 如果下一个节点为空,则把新节点设置在next的位置上
- this.next = newNode ;
- }else{ // 如果不为空,则需要向下继续找next
- this.next.add(newNode) ;
- }
- }
- public void print(){
- System.out.print(this.data + "\t") ; // 输出节点内容
- if(this.next!=null){ // 还有下一个元素,需要继续输出
- this.next.print() ; // 下一个节点继续调用print
- }
- }
- public boolean search(String data){ // 内部搜索的方法
- if(data.equals(this.data)){ // 判断输入的数据是否和当前节点的数据一致
- return true ;
- }else{ // 向下继续判断
- if(this.next!=null){ // 下一个节点如果存在,则继续查找
- return this.next.search(data) ; // 返回下一个的查询结果
- }else{
- return false ; // 如果所有的节点都查询完之后,没有内容相等,则返回false
- }
- }
- }
- public void delete(Node previous,String data){
- if(data.equals(this.data)){ // 找到了匹配的节点
- previous.next = this.next ; // 空出当前的节点
- }else{
- if(this.next!=null){ // 还是存在下一个节点
- this.next.delete(this,data) ; // 继续查找
- }
- }
- }
- };
- private Node root ; // 链表中必然存在一个根节点
- public void addNode(String data){ // 增加节点
- Node newNode = new Node(data) ; // 定义新的节点
- if(this.root==null){ // 没有根节点
- this.root = newNode ; // 将第一个节点设置成根节点
- }else{ // 不是根节点,放到最后一个节点之后
- this.root.add(newNode) ; // 通过Node自动安排此节点放的位置
- }
- }
- public void printNode(){ // 输出全部的链表内容
- if(this.root!=null){ // 如果根元素不为空
- this.root.print() ; // 调用Node类中的输出操作
- }
- }
- public boolean contains(String name){ // 判断元素是否存在
- return this.root.search(name) ; // 调用Node类中的查找方法
- }
- public void deleteNode(String data){ // 删除节点
- if(this.contains(data)){ // 判断节点是否存在
- // 一定要判断此元素现在是不是根元素相等的
- if(this.root.data.equals(data)){ // 内容是根节点
- this.root = this.root.next ; // 修改根节点,将第一个节点设置成根节点
- }else{
- this.root.next.delete(root,data) ; // 把下一个节点的前节点和数据一起传入进去
- }
- }
- }
- }
- public class LinkDemo02{
- public static void main(String args[]){
- Link l = new Link() ;
- l.addNode("A") ; // 增加节点
- l.addNode("B") ; // 增加节点
- l.addNode("C") ; // 增加节点
- l.addNode("D") ; // 增加节点
- l.addNode("E") ; // 增加节点
- System.out.println("======= 删除之前 ========") ;
- l.printNode() ;
- // System.out.println(l.contains("X")) ;
- l.deleteNode("C") ; // 删除节点
- l.deleteNode("D") ; // 删除节点
- l.deleteNode("A") ; // 删除节点
- System.out.println("\n====== 删除之后 =========") ;
- l.printNode() ;
- System.out.println("\n查询节点:" + l.contains("B")) ;
- }
- }