以下为《C202_Java面向对象_学习笔记》的无排版文字预览,完整内容请下载
***《Java面向对象》学习笔记态度?方法?知识
邵某某
2017/11/26
目 录
课程基本信息 1
1 面向对象概述 2
1.1 程序设计方法 2
1.2 面向对象基本概念 3
1.3 面向对象的基本特征 3
2 类与对象 5
2.1 类和对象的定义与使用 5
2.2 构造函数和垃圾回收 5
2.3 访问权限控制和封装 6
2.4 静态 7
2.5 内部类 8
3 继承与多态 9
3.1 继承的基本概念 9
3.2 类的继承 9
3.3 多态 10
3.4 final 10
4 抽象类与接口 12
4.1 抽象类 12
4.2 接口 12
4.3 匿名内部类 13
5 泛型 14
5.1 泛型的引入 14
5.2 泛型的定义和使用 14
课程基本信息
课程代码:C202
课程名称:Java面向对象
学习时长:5天
教学目标:
熟练掌握面向对象基本概念;
熟练掌握面向对象的分析和设计方法;
教学内容:
内容知识点课时
面向对象概述两种程序设计方法分析对比、面向对象的基本概念和特征3
类与对象类的定义、成员变量和成员方法、构造函数、封装的作用和使用、访问权限控制。重载、this、static、内部类、包
12
继承与多态
继承的概念、继承的实现案例、重写、super、final、多态
6
抽象类与接口
抽象类的概念和实现、接口的概念和实现
6
泛型
泛型的概念和实现
3
面向编程:在解决问题中,注意的是解决问题的每一个步骤和过程。
面向对象:注重的是在问题中涉及到的对象,以及对象之间的关系
核心思想
缺点
算法
面向编程
自顶向下,逐步求精,也就是把功能分解
一旦数据结构发生修改,就必须要修改操作代码
可重用性差
可维护性差,维护成本高
程序=数据结构+算法
相对优点
面向对象
分解数据
数据、操作数据是一个整体
数据修改只涉及对该数据的操作(封装)
可重用性强(继承)
可维护性好,维护成本低
程序=数据结构+消息
1 面向对象概述
程序设计方法
面向对象基本概念
对象:万物皆对象,对象是由静态的属性和动态的方法组成。
类:一组具有相同属性和行为对象的抽象事物。
消息:向某个对象发送请求。(如:手机来电)
方法:对象对收到请求的响应。(如:手机收到来电会震动提示)
面向对象的基本特征
抽象:从一个具体的对象中提取提取一组数据,去除非本质和特性的属性,保留本质的、共性的。
比如学生,有很多的属性(学号、姓名、性别、身高、体重、血型、专业、班级、成绩),如果我们要做一个学生成绩管理系统,我们应该关注的,除了学生的基本信息(姓名、性别等),还要关注和学习相关的属性(学号、专业、班级、成绩),不用关注他的血型、体重、身高等跟成绩无关的属性。而如果我们要做的是一个学生健康管理系统,那么除了基本属性,身高、 体重就是学生的本质属性。
封装:给对象一个边界,将内部信息尽量的隐藏,只保留对外的操作接口。比如:显示器内部的元器件是看不到的,也不允许随意摆弄,而是留下电源、信号接口以及调节亮度的按钮。封装使得对象更加的安全,容易。
继承:继承是允许后代直接使用前辈直接拥有的。比如,长得像父母就是继承了父母的部分基因。如果自然界中没有继承,世界就依然是混沌状态,所有生物的出现都是从初始状态,也就没有了进化。继承是一种代码重用的机制,使得代码更省略、更可靠、更高效。
比如:一个拥有卡车设计和制造能力的企业,要设计消防车,显然是比没有经验的企业更加高效和可靠,因为他继承了之前的设计和制造能力,只是需要在此基础上稍加改动即可。
多态:同样的消息发送给不同的对象,不同的对象做出的响应可能有所不同。比如:跑步运动员和游泳运动员,都有“出发”的这个方法,当收到裁判员传来的消息时,都开始执行“出发”,但是他们所做出来的动作是不相同的。
面向对象程序设计方法实际上是用我们习惯的人的思维方式去思考和设计,其实是返璞归真,理解起来也不会很难。
2.类与对象
2.1 类和对象的定义与使用
类的定义:
Class 类名{
数据成员-静态属性
成员函数-动态行为
}
对象的定义:
类名 对象名
与 int a的含义差不多
类定义的“{}”就是类的“外壳”,提供了封装,private声明的成员外面是不能访问的,而public可以。
引用:一个储存了某个对象地址的变量,它储存的不是对象本身,而是对象的地址。
Point point=new Point();的含义是:首先实例化一个对象(new Point()),然后定义一个引用point指向这个实例。
point=point1
不是讲实例point赋值给point1,而只是改变了引用的关系,即point也指向了point1指向的实例
/
2.2 构造函数和垃圾回收
为什么需要有构造函数?
构造函数是完成对象的初始化,这个当然可以定义一个成员方法予以实现。但是这个方法必须显式调用,否则就可能因未初始化出现错误。
我们希望这样的方法能够被自动调用,能被自动调用,那么它的名字一定是独一无二的,什么样的名字才是独一无二的呢?——以类名作为方法名。这就是构造函数。
构造函数,是在对象实例化时自动被系统调用,该函数名必须独一无二。对于一个类来说,就是将一个类名作为函数名。
构造函数不需要程序员去定义返回值,他是系统自动决定的,void也不行。
构造函数无法、也无需指定返回值,它是自动被调用的。
函数重载
多个函数使用同一个函数名,系统根据参数自动调用相应的函数。
函数重载解决了标识符统一的问题。
拷贝构造函数(深度拷贝,浅度拷贝)
用一个已经存在的本类的对象去复制新的对象
例如 public Circle(Circle c){
this.p=c.p;
this.r=c.r;
}
垃圾回收:所谓的“垃圾”是指之前系统分配的内存单元,但是现在没用了,
再具体的讲,就是没有引用指向它。对于“垃圾”来讲,程序员不需要自己去回收,而是系统提供的垃圾回收机制自动回收,当程序员觉得有必要时,也可以强制让系统回收。
2.3 访问权限控制和封装
方法的访问控制(四种访问权限):
/
封装的要领,是站在用户的角度去思考怎么去描述一个类,它应该有什么属性和行为,而不是去考虑如何实现。
2.4 静态
静态成员修饰的成员与一般的成员有何区别呢?
静态成员只初始化一次,之后就不会初始化,静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它***有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见
一般的成员是每个对象有一份数据,而静态成员是属于类的,即所有对象所共享;
一般成员的访问方式:对象名.成员名,而静态成员的访问方式:类名.成员名。
this是“这个”、“当前”的意思,每一个成员方法都隐含有一个参数(this)。
比如
public void print(){ System.out.println("学号:"+sno); System.out.println("姓名:"+name); System.out.println("性别:"+(sex==MALE?"男":"女")); System.out.println("学历:"+(level==UNDERGRADUATION?"本科":"专科"));}
中的
System.out.println("学号:"+sno);严格来讲,应该写成
System.out.println("学号:"+this.sno);
静态常量,静态成员变量,静态成员方法,静态代码块
静态方法属于类,不属于对象
静态方法没有this
静态方法只能访问静态成员
静态方法和实例方法的区别主要体现在两个方面:
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量XX态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
一般的成员都是通过构造函数去完成初始化(实例化对象时),而静态成员则是在加载类的时候(也就是实例化之前)初始化
静态代码块:
public static int n;
static{
n=1;
}
静态成员的初始化都写在静态代码块里static里
2.5 内部类
内部类是指在一个类的内部定义的类
内部类可以自由访问外部类的所有成员
内部类可以作为成员类(在外部类中定义,和成员方法平行)和方法内部类(定义在外部类的成员方法里面)。
内部类的实例化:
Computer.Cpu cpu=new Computer().new Cpu();System.out.println(cpu.getY());
当一个类离开另一个类而无法单独存在或者说没有意义的情况下,使用内部类是最合适的(如:CPU离开计算机类,单独存在就没有意义了)
面对对象设计
(1)类的设计:考虑应该由哪些属性去描述这个类,这个类应该提供什么方法?
(2)方法(函数)设计:函数名、参数和返回值类型
如果需要返回多个结果,函数返回值如何设计
(1)可以将多个返回结果融在一个结果中,用特定的值表示其中的一个结果。比如查找函数需要返回是否找到以及找到的话下标是多少两个结果。可以将这两个结果并在一个整型返回值中,用-1表示没找到,找到的话就返回下标。这样设计的理由是下标不可能为-1,所以-1可以表示特定的含义。
(2)将多个返回值封装成一个类对象
(3)可以考虑使用输出型参数,在Java中就只能使用引用类型了。
2.6匿名内部类
3 继承与多态
3.1 继承的基本概念
什么是继承?
继承就是可以直接使用前辈的属性和方法。
/
为什么需要继承?
自然界中如果没有继承,那一切都是出于混沌状态。在软件开发中,我们可以借鉴自然界的机制,已经有的东西我们希望能够直接拿来用(复用)而不用重复做。而且类之间本来可能就存在着层次关系,比如小学生,中学生,大学生都是学生。
案例:定义人和员工类
定义人
public class Person { private String id; //身份证号码 private String name; //姓名 private String sex; //性别 public Person(String id, String name, String sex) { this.id = id; this.name = name; this.sex = sex; } public void print(){ System.out.println(id); System.out.println(name); System.out.println(sex); }}
定义员工类
public class Employee { private String id; private String name; private String sex; private int salary;//工资 public Employee(String id, String name, String sex, int salary) { this.id = id; this.name = name; this.sex = sex; this.salary = salary; } public void print(){ System.out.println(id); System.out.println(name); System.out.println(sex); System.out.println(salary); }}
测试程序
public class Test { public static void main(String[] args) { Person p = new Person("******","zhang","男"); Employee e = new Employee("4***078","wang","女",3600); p.print(); e.print(); }}
这样做存在的问题:
(1)重复劳动:人有姓名、性别等属性,员工中又重复定义了,将来可能在学生、教师等类中还要重复。
(2)信息不一致:比如人的性别用0-1表示,而员工类中可能用“男/女”来表示,导致使用上的混乱。
那么能否在员工类中使用已有的人类的姓名、性别等呢——继承。
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
3.2 类的继承
如何使用继承呢?
把上面的员工类改写一下——继承自Person类
public class Employee extends Person { private int salary;//工资 public Employee(String id, String name, String sex, int salary) { super(id, name, sex); this.salary = salary; } @Override public void print() { super.print(); System.out.println(salary); }}
使用继承就很好地解决了上面提出的两个问题。
extends是“拓展、延伸”的含义,public class Employee extends Person 就是声明一个叫做Employee的类,它是在Person类的基础上进行拓展,专业术语称之为继承自Person类。
super是“超”的含义,Person类相对于Employee类就是超类,通俗一点的说法是父类。
子类继承了父类的属性和方法,当然也可以在此基础上进行拓展——加和改。在这个案例中加了“薪水”属性,改了“打印”方法。这里有一个专业术语——重写(override)。
继承不仅仅解决了刚才的两个问题,还使得类有层次结构,逻辑上也更加合理。比如“员工”也是“人”。
3.3 访问权限控制(补充)
在之前已经讲过private和public
private:私有的,外部是不可访问的
public:公有的,外部可以访问
protected:保护的,外部访问如果是来自子类是可以的,其它的拒绝。
default:自学
也就是外部分为两种:子类和非子类,对于子类而言,protected等同于public,而对于非子类protected又等同于private。
比如在Employee类中,如果name是私有的,那么这个访问就是被拒绝的,而如果是保护的则可以。
public void print() { super.print(); System.out.println(name); System.out.println(salary);}
即使是保护的成员,对于非子类的外部访问也是拒绝的,比如在测试类中就是不可以。
public class Test { public static void main(String[] args) { Person p = new Person("******","zhang","男"); Employee e = new Employee("4***078","wang","女",3600); p.print(); e.print(); System.out.println(e.name); }}
3.3 多态
多态就是将同一个消息发送给不同对象时,它们所做的响应可能是不同的。比如说动物都有“叫”的方法,但是狗是“汪汪”,而猫是“喵喵”,当它们接收到被打的消息时,所做的响应是不同的。
案例:打动物
定义一个动物类,实现“叫”的方法
public class Animal { public void shout(){ System.out.println("吼吼……"); }}
定义一个狗类,继承自动物类,重写“叫”的方法
public class Dog extends Animal { @Override public void shout() { System.out.println("汪汪……"); }}
定义一个猫类
public class Cat extends Animal { @Override public void shout() { System.out.println("喵喵……"); }}
测试程序
public class Test { public static void main(String[] args) { Dog d = new Dog(); Cat c = new Cat(); hit(d); hit(c); } private static void hit(Cat c) { c.shout(); } private static void hit(Dog d) { d.shout(); }
}
在测试程序中定义了两个“打”的方法,这种做法是比较笨拙的,有几种动物就需要定义几个方法,这个可能没完没了。有没有一个一劳永逸的方法?
不要传递Dog或者Cat等对象,而是传递一个Animal类对象就可以解决上面的问题。测试程序修改为
public class Test { public static void main(String[] args) { Dog d = new Dog(); Cat c = new Cat(); hit(d); hit(c); }
private static v 内容过长,仅展示头部和尾部部分文字预览,全文请查看图片预览。
方法
init
初始化
drawBoard
绘制棋盘
drawChess
绘制棋子
handle
接收并处理用户的落子指令
6.2系统设计
a. 棋盘(Board)
考虑到棋盘的属性在游戏过程中是不变的,所以可以将其属性和方法设计成静态的,那么初始化的方法就应该由静态代码块来完成。
转换:Point convert(int x, int y)
增加一个坐标类Point,描述行号和列号
b. 棋局(Chess)
定义常量(0-无子,1-黑子,-1-白子)
初始化: void init(),也可以使用构造函数
判断是否某个落点有棋子:boolean exist(Point p)
判断输赢:int isWin(Point p)
落子:void add(Point p)
c. 游戏
初始化 void init(),也可以使用构造函数
处理落子指令 void handle(int x, int y)
绘制棋盘void drawBoard()
绘制棋子void drawChess(Point p,int turn)
[文章尾部最后500字内容到此结束,中间部分内容请查看底下的图片预览]请点击下方选择您需要的文档下载。
以上为《C202_Java面向对象_学习笔记》的无排版文字预览,完整内容请下载
C202_Java面向对象_学习笔记由用户“liweiminhai”分享发布,转载请注明出处