面向对象
1、面向过程&面向对象
-
面向过程思想
-
步骤清晰简单,第一步做什么,第二步做什么。。。
-
面向过程适合处理一些较为简单的问题
-
-
面向对象思想
-
物以类聚,分类的思维方式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
-
面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
-
-
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,任然需要面向过程的思路去处理。
2、面向对象
-
面向对象编程(Object-Oriented Programming,OOP)
-
面向对象编程的本质就是;以类的方式组织代码,以对象的组织(封装)数据。
-
对象:现实世界中,随处可见的·一种事物就是对象。对象是事物存在的实体。通常将对象划分为两个部分:
-
静态部分:即属性。
-
动态部分:方法。
-
-
类:如果将现实世界中的一个事物抽象成对象,具有相同特性和行为的一类事物就称为类,类就是这类对象的统称。类是封装对象的属性和行为的载体。
-
三(四)大特性
-
封装
封装是面向对象编程的核心思想。将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。
-
继承
当处理一个问题时,可以将一些有用的类保留下来,这些类通常有相同的属性,甚至相同的方法,当遇到同样问题时可以拿来复用。例如鸽子具有与鸟类相同的属性和行为。便可以在创建信鸽类时将鸟类拿来复用,并且保留鸟类具有的属性和行为。
-
多态
将父类对象应用于子类的特征就是多态:多态性允许一统一的风格编写程序,以处理种类繁多的已存在的类以及相关类。该统一风格可以由父类来实现,根据父类统一风格可以由父类实现,就可以实例化子类的对象。由于整个事件的处理都只依赖于父类的方法,所以日后只要维护和调整父类的方法即可,这样就降低了维护的难度,节省了时间。
-
抽象
核心的编程思想
-
-
从认识角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
-
从代码运行角度考虑是先有类后有对象。类是对象的模板。
二、回顾方法的定义与调用
1、方法的定义
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
-
修饰符:修饰符是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
-
返回值类型:方法可能会返回值,returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType的关键字是void。
-
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递只给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
-
形式参数:在方法被调用时用于接收外界输入的数据。
-
实参:调用方法时实际传给方法的数据。
-
-
方法体:方法体包含具体的语句,定义该方法的功能。
2、方法的调用
-
调用方法:对象名.方法名(实参列表)
-
java支持两种调用方法的方式,根据方法是否返回值来选择。
-
当方法返回一个值的时候,方法调用通常被当做一个值,例如:
int larger = max(30,40); -
如果方法返回值是void,方法调用一定是一条语句。
System.out.println("Hello World!");
-
####
三、对象的创建分析
1、权限修饰符
| 访问包位置 | private | protected | public |
|---|---|---|---|
| 本类 | 可见 | 可见 | 可见 |
| 同包其他类或子类 | 不可见 | 可见 | 可见 |
| 其他包的类或子类 | 不可见 | 不可见 | 可见 |
2、类的构造方法:
-
构造方法没有返回值,也不能写void
-
构造方法的名称要与本类的名称相同
权限修饰符 方法名(){
//构造方法体
}
3、使用new关键字创建对象
-
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器(构造方法)的调用。
package OOP;
public class Student {
//属性,字段
String name;
int age;
//方法 alt + insert
public /*static*/ void study(){
//在静态方法中不可以使用this关键字
System.out.println(this.name + "在学习");
}
public static void main(String[] args) {
//实例化
Student xiaoming = new Student();
Student xiaohong = new Student();
xiaoming.age = 3;
xiaoming.name = "小明";
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
xiaohong.name = "小红";
xiaohong.age = 5;
System.out.println(xiaohong.name);
System.out.println(xiaohong.age);
/*studey();*/ //在静态方法中不可以直接调用非静态方法,所以报错
}
}
4、对象的比较
package OOP;
public class Demo05 {
public static void main(String[] args) {
String c1 = new String("abc");
String c2 = new String("abc");
String c3 = c1;
//使用“==”运算符比较c2与c3
System.out.println("c2 == c3的运算结果为:" + (c2 == c3));//结果为falsa
System.out.println("c2.equals(c3)的运算结果为:" + c2.equals(c3));//结果为true
}
}
-
equals()方法是String类中的方法,他用于比较两个对象引用所指的内容是否相等;而“==”运算符比较的是两个对象引用的地址是否相等。
5、对象的销毁
-
两种情况java虚拟机会将对象视为“垃圾”:
-
对象引用超过其作用范围,这个对象被视为垃圾
-
将对象赋值为NULL
-
-
虽然垃圾回收机制已经很完善,但垃圾回收器只能回收那些由new操作符创建的对象。
四、面向对象三大特性
1、封装
-
该藏的藏,该漏的漏
-
我们程序设计要追求“高内聚,低耦合”。
-
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉。
-
低耦合:仅暴露少量的方法给外部使用。
-
-
-
封装(数据的隐藏)
-
通常,应进制直接访问一个对象中数据的实际表示,而应通过接口操作来访问,这称为信息隐藏。
-
-
属性私有,get/set
package OOP;
public class Student1 {
/*
1.提高程序的安全性,可以保护数据
2.可以隐藏代码的实现细节
3.统一接口
4.提高了系统的可维护性
*/
//属性私有
private int id;
private String sex;
private String name;
private int age;
//提供一些可以操作这个属性的方法
//提供一些public的get、set方法
//alt + insert 可智能生成get/set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name){
//可在set方法里面设置一些安全性检查,例如判断name是否合法
this.name = name;
}
public int getAge() {
return age;
}
//可在set方法里面设置一些安全性检查,例如判断age是否合法
public void setId(int age) {
if(age>120||age<0){
this.age = 3;
}else{
this.age = age;
}
}
}
2、继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好地建模
-
extends的意思是”扩展“。子类是对父类的扩展,ctrl + h 可以显示出继承树
-
继承并不只是扩展父类的功能,他还可以重写父类的构造方法。
-
重写(覆盖):就是在子类中将父类的成员方法的名称和参数列表保留,重写成员方法的实现内容,更改成员方法的存储权限,或是修改成员方法的返回值类型
-
重构:特殊的重写方式,子类与父类的成员方法返回值、方法名称、参数类型及个数完全相同,唯一不同的是方法实现内容。
-
重写父类方法时,修改方法的修饰权限只能从小的范围到大的范围改变。例如父类的doSomething()方法的权限为protected,子类中不能将其改成private。(public > protected > Default >private)
-
重写都是方法的重写,和属性无关
-
抛出的异常:范围可以被缩小,但不能扩大
-
alt + insert + override :重写快捷键
-
被final修饰的类不能被继承
package OOP;
import java.security.ProtectionDomain;
public /*final*/ class Test {
public Test() {//构造方法
//SomeSentence
}
public void doSomething() {//成员方法
//SomeSentence
}
protected Test dolt(){//返回值为Test类型
return new Test();
}
}
class Test2 extends Test{//继承父类
public Test2(){//构造方法
super();//调用父类构造方法
super.doSomething();//调用父类成员方法
}
public void doSomethingNew() {//新增方法
//SomeSentence
}
public void doSomething() {//重写父类方法
//SomeNewSentence
}
protected Test2 dolt(){//重写父类方法,返回值为Test2类型
return new Test2();
}
}
-
-
java中类只有单继承,没有多继承
-
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有以来、组合、聚合等。
-
继承关系的俩个类,一个为子类(派生类),一个为父类(基类),使用关键字extends来表示。子类和父类之间,从意义上将应该具有“is a”的关系,例如“学生” is a “人 ”
-
Object类
-
java中,所有的类都直接或者间接继承Object类
-
Object类中主要包括clone(),finalize(),equals(),toString()等方法
-
Object类中的getClass() ,notify() ,notifyAll() ,wait()等方法不能被重写,因为这些方法被定义为final类型。
-
-
super详解
-
注意点:
-
super调用父类的构造方法,必须在构造方法的第一个
-
super必须只能出现在子类的方法或者构造方法中!
-
super和this不能同时调用构造方法
-
-
和this的区别
-
代表的对象不同:
-
this代表本身调用者这个对象
-
super代表父类对象的应用
-
-
前提不同
-
this:没有继承也可以使用
-
super:只有在继承条件才可以使用
-
-
构造方法
-
this():本类的构造方法
-
super():父类的构造方法
-
-
-
3、多态
-
即同一方法可以根据发送对象的不同二采用多种不同的行为方式
-
利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
-
多态存在的条件
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象
-
-
注意:多态是方法的多态,属性没有多态
-
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
-
子类能调用的方法都是自己的或者是继承父类的
-
父类型可以指向子类,但是不能调用子类独有的方法
-
-
instanceof 与 类型转换
-
instanceof
X x = new Y();
System.out.printfln(X instanceof Y);//X与Y之间是否存在父子关系,若存在则返回true,否则返回false -
类型转换(高 (父) -- > 低(子))
Person obj = new Student();
//obj不能直接用子类的方法,可以强制转换为子类后调用子类方法
Student student = (Student)obj;
student.go();
//也可以用以下方式
((Student)obj).go(); -
-
父类引用指向子类的对象
-
把子类转换为父类:向上转型
-
把父类转换为子类:强制转换
-
方便方法的调用,减少重复的代码
-
-
五、抽象类与接口
1、抽象类
-
抽象类的关键字:abstract
-
使用abstract关键字定义的类称为抽象类,而是用这个关键字定义的方法称为抽象方法。
-
抽象方法没有方法体,这个方法本身没有任何意义,除非他被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承之外没有任何意义
-
抽象类中可以没有抽象方法,但是只要一个类中有一个抽象方法,此类就被标记为抽象类。
-
抽象类被继承后需要实现其中的所有抽象方法,也就是保证相同的方法名称、参数列表和相同返回值类型创建出非抽象方法,当然也可以是抽象方法,则子类也为抽象类
-
抽象类,不能用new关键字来创建对象,只能由子类重写来实现
-
定义抽象方法
public abstract class Test{
abstract void doSomething();//定义抽象方法
}
2、接口
(1)接口简介
-
接口是抽象的延伸,可以把它看作纯粹的抽象类,接口中的所有方法都没有方法体
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法),有构造方法
-
接口:只有规范,没有构造方法
-
接口就是规范,定义的一组规则,体现了现实世界中“如果你是...则必须能....”的思想、
-
接口的本质是契约,就像是法律一样,定制好后都遵守
-
OO的精髓,是对对象的抽象,最能体现这一点的就是接口
-
-
-
声明接口的关键字是:interface
public interface/*关键字*/ drawTest/*接口名*/{
//在接口中定义的任何字段都自动是static和final的
void draw(); //接口内的方法,省略abstract关键字
}
//public:接口可以像类一样被权限修饰符修饰,但public关键字仅限用于接口在与其同名的文件中被定义
//接口中,方法必须被定义成public或abstract形式,其他修饰符不被java编译器认可
(2)接口可以多继承
//一个类实现一个接口,可以用implements关键字
public class Parallelogram extends Quadrangle implements drawTest{
...//
}
//多继承语法格式
public class 类名 implements 接口1,接口2...,接口N
七、内部类及OOP实战
-
内部类就是在一个类的内部再定义一个类,比如,在A类中定义一个B类,那么B类性对于A类来说就称为内部类,而A类相对B类来说就是外部类。
1、成员内部类
(1)、成员内部类简介
-
在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量(私有属性)
-
定义:
public class Outer{//外部类
private class Inner{//内部类
}
}
-
调用
public class Application{
public static void main(String[] ages){
Outer.Inner 名称 = Outer.new Inner();
Inner.方法();
}
}
(2)内部类向上转型为接口
-
略
(3)使用this关键字获取内部类与外部类的引用
-
略
2、静态内部类
-
在内部类前添加修饰符static,这个内部类就变成静态内部类了。
-
一个静态内部类中可以声明static成员,但是在非静态内部类中不可以声明静态成员
-
静态内部类不可以使用外部类的非静态成员
-
特点
-
如果创建静态内部类的对象,不需要其外部类的对象
-
不能从静态内部类的对象中访问非静态外部类的对象
-
3、局部内部类
-
在类的方法或任意的作用域中均可以定义内部类
interface OutInterface2{//定义一个接口
}
class OuterClass3{
public OutInterface2 doit(final String X){//doit()方法参数为final类型
//在doit()方法中定义一个内部类
class InterClass2 implements Outerface2{
InnerClass2(String s){
s = x;
System.out.println(s);
}
}
return new InnerClass2("doit");
}
}
4、匿名内部类
public class Test{
public static void main(String[] ages){
//没有名字初始化类,不用将实例保存到变量中~
new Apple().eat();
}
}
class Apple{
public void eat(){
System.out.println("1);
}
}
5、内部类的继承
-
内部类和其他普通类一样,可以被继承。
-
在某个类继承内部类时,必须硬性给与这个类一个带参数的构造方法,并且该构造方法的参数为需要继承内部类的外部类的引用,同时在构造方法体中使用a.super()语句,这样才为继承提供了必要的对象引用。
public class OutputInnerClass extends ClassA.ClassB{//继承内部类ClassB
public OutputInnerClass(ClassA a){
a.super();
}
}
calss ClassA{
class ClassB{
}
}
浙公网安备 33010602011771号