面向对象
2021-07-28 15:17:22 2 举报
AI智能生成
Java 面向对象粗略小结
作者其他创作
大纲/内容
关键字
this
this:在方法内使用时表示当前对象,在构造器内使用时表示当前正在初始化的对象
使用:this可以调用属性、方法、构造器。this.属性名调用属性,this.方法名(形参列表)调用方法,this(形参列表)调用构造器。注:this调用构造器时只能在构造器中调用,写在构造器中第一行,并且一个构造器只能调用一次this(形参列表)
super
在Java类中使用super来调用父类中的指定操作
super可用于访问父类中定义的属性((super.父类属性名)
super可用于调用父类中定义的成员方法(super.父类方法名)
super可用于在子类构造器中调用父类的构造器(super.())
注意:
尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
super的追溯不仅限于直接父类
super和this的用法相像,this代表本类对象的引用,super代表父类的内存
空间的标识
空间的标识
子类中所有的构造器默认都会访问父类中空参数的构造器
当父类中没有空参数的构造器时,子类的构造器必须通过this(参
数列表)或者super(参数列表)语句指定调用本类或者父类中相应的
构造器。同时,只能”二选一”,且必须放在构造器的首行
数列表)或者super(参数列表)语句指定调用本类或者父类中相应的
构造器。同时,只能”二选一”,且必须放在构造器的首行
如果子类构造器中既未显式调用父类或本类的构造器,且父类中又
没有无参的构造器,则编译出错
没有无参的构造器,则编译出错
this和super的区别:
import
为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类
或全部类(.*)。import语句告诉编译器到哪里去寻找类。
或全部类(.*)。import语句告诉编译器到哪里去寻找类。
格式:import 包名. 类名;
package
package语句作为Java源文件的第一条语句,指明该文件中定义的类所在
的包。
的包。
使用格式:package 顶层包名.子包名 ;
static
使用范围:在Java类中,可用static修饰属性、方法、代码块、内部类
被static所修饰的结构作为该类各个对象之间共享的结构,不用创建对象也可以调用静态成员
被static修饰后的成员具备以下特点:
随着类的加载而加载
优先于对象存在
修饰的成员,被所有对象所共享
访问权限允许时,可不创建对象,直接被类调用
类变量:
类变量(类属性)由该类的所有实例共享
调用:
在类内部:可以和属性一样调用,也可以用:类名.类变量名
在类外部:对象名.类变量名或类名.类变量名
类方法:
没有对象的实例时,可以用类名.方法名()的形式访问由static修饰的类方法。
在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
因为不需要实例就可以访问static方法,因此static方法内部不能有this也不能有super。
static修饰的方法不能被重写
final
在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”
final标记的类不能被继承。提高安全性,提高程序的可读性。
如:String类、System类、StringBuffer类
如:String类、System类、StringBuffer类
final标记的方法不能被子类重写。
比如:Object类中的getClass()。
比如:Object类中的getClass()。
final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次。
final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋值,然后才能使用。
final double MY_PI = 3.14;
final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋值,然后才能使用。
final double MY_PI = 3.14;
static final:全局常量
instanceof
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
设计模式
单例模式
就是采取一定的方法保证在整个的软件系统中,对
某个类只能存在一个对象实例
某个类只能存在一个对象实例
类型
饿汉式
懒汉式
其他类
Object
Object类是所有Java类的根父类
Object类是所有Java类的根父类
Object中常用结构
==操作符与equals方法
基本类型比较值:只要两个变量的值相等,即为true。
引用类型比较引用(是否指向同一个对象):只有指向同一个对象时,==才
返回true。
返回true。
用“==”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本
数据类型除外),否则编译出错
数据类型除外),否则编译出错
equals():所有类都继承了Object,也就获得了equals()方法。还可以重写
只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象。
格式:obj1.equals(obj2)
特例:当用equals()方法进行比较时,对类File、String、Date及包装类
(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对
象;原因:在这些类中重写了Object类的equals()方法。
(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对
象;原因:在这些类中重写了Object类的equals()方法。
当自定义使用equals()时,可以重写。用于比较两个对象的“内容”是否都
相等
相等
toString() 方法
toString()方法在Object类中定义,其返回值是String类型,返回类名和它
的引用地址。
的引用地址。
在进行String与其它类型数据的连接操作时,自动调用toString()方法
Date now=new Date();
System.out.println(“now=”+now); 相当于
System.out.println(“now=”+now.toString());
Date now=new Date();
System.out.println(“now=”+now); 相当于
System.out.println(“now=”+now.toString());
可以根据需要在用户自定义类型中重写toString()方法
如String 类重写了toString()方法,返回字符串的值。
s1=“hello”;
System.out.println(s1);//相当于System.out.println(s1.toString());
如String 类重写了toString()方法,返回字符串的值。
s1=“hello”;
System.out.println(s1);//相当于System.out.println(s1.toString());
基本类型数据转换为String类型时,调用了对应包装类的toString()方法
int a=10; System.out.println(“a=”+a);
int a=10; System.out.println(“a=”+a);
包装类
针对八种基本数据类型定义相应的引用类型—包装类(封装类)
有了类的特点,就可以调用类中的方法,Java才是真正的面向对象
基本数据类型包装成包装类的实例 ---装箱
通过包装类的构造器实现:
int i = 500; Integer t = new Integer(i);
int i = 500; Integer t = new Integer(i);
还可以通过字符串参数构造包装类对象:
Float f = new Float(“4.56”);
Long l = new Long(“asdf”); //NumberFormatException
Float f = new Float(“4.56”);
Long l = new Long(“asdf”); //NumberFormatException
获得包装类对象中包装的基本类型变量 ---拆箱
调用包装类的.xxxValue()方法:
boolean b = bObj.booleanValue();
boolean b = bObj.booleanValue();
JDK1.5之后,支持自动装箱,自动拆箱。但类型必须匹配。
字符串转换成基本数据类型
通过包装类的构造器实现:
int i = new Integer(“12”);//先把字符串转化成包装类,然后自动拆箱成基本数据类型
int i = new Integer(“12”);//先把字符串转化成包装类,然后自动拆箱成基本数据类型
通过包装类的parseXxx(String s)静态方法:
Float f = Float.parseFloat(“12.1”);
Float f = Float.parseFloat(“12.1”);
基本数据类型转换成字符串
调用字符串重载的valueOf()方法:
String fstr = String.valueOf(2.34f);
String fstr = String.valueOf(2.34f);
更直接的方式:
String intStr = 5 + “”
String intStr = 5 + “”
类
类的定义
类是对具有相同属性的一类事物的统称,类是一个抽象的概念,具体实例化为对象后,通过对具体的对象调用该类的某一方法或属性,从而实现特定的功能,体现了java中万事万物皆对象,而类则是创建对象的前提
定义方式:权限修饰符 class 类名(extends 父类名)(implements 接口名)(throws 异常类型){ }
属性
属性也称为成员变量
定义方式:权限修饰符 (static) (final) 属性类型 属性名
方法
方法体现的是类的功能
定义方式:权限修饰符 (static) (final) 返回值类型 方法名(形参列表){方法体}
return:当方法有返回值时,return返回参数并结束方法,当方法没有返回值时,return仅结束方法
重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数
类型不同即可。
类型不同即可。
可变个数形参:参数类型... 参数名
方法参数的值传递机制:
形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
构造器
作用:创建对象;给对象进行初始化
定义:权限修饰符 类名(参数列表){初始化语句}
每一个类中都有构造器,构造器根据参数列表也可以重载
代码块
代码块(或初始化块)的作用:对Java类或对象进行初始化
代码块(或初始化块)的分类:一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块(static block),没有使用static修饰的,为非静态代码块。
static代码块通常用于初始化static的属性
静态代码块:用static 修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5. 静态代码块的执行要先于非静态代码块。
6. 静态代码块随着类的加载而加载,且只执行一次。
2. 可以对类的属性、类的声明进行初始化操作。
3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5. 静态代码块的执行要先于非静态代码块。
6. 静态代码块随着类的加载而加载,且只执行一次。
非静态代码块:没有static修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
5. 每次创建对象的时候,都会执行一次。且先于构造器执行。
2. 可以对类的属性、类的声明进行初始化操作。
3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
5. 每次创建对象的时候,都会执行一次。且先于构造器执行。
内部类
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内
部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使
用内部类。
部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使
用内部类。
在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者
称为外部类。
称为外部类。
Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完
整的名称。
Inner class的名字不能与包含它的外部类类名相同;
整的名称。
Inner class的名字不能与包含它的外部类类名相同;
分类: 成员内部类(static成员内部类和非static成员内部类)
局部内部类(不谈修饰符)、匿名内部类
局部内部类(不谈修饰符)、匿名内部类
成员内部类作为类的成员的角色:
1.和外部类不同,Inner class还可以声明为private或protected;
2.可以调用外部类的结构
3.Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员
变量;
2.可以调用外部类的结构
3.Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员
变量;
成员内部类作为类的角色:
1. 可以在内部定义属性、方法、构造器等结构
2.可以声明为abstract类 ,因此可以被其它的内部类继承
3.可以声明为final的
4.编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)
2.可以声明为abstract类 ,因此可以被其它的内部类继承
3.可以声明为final的
4.编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)
注意:
1. 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员
内部类中才可声明static成员。
2. 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
3. 成员内部类可以直接使用外部类的所有成员,包括私有的数据
4. 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的
内部类中才可声明static成员。
2. 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
3. 成员内部类可以直接使用外部类的所有成员,包括私有的数据
4. 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的
如何声明局部内部类
class 外部类{
方法(){
class 局部内部类{
}
}
{
class 局部内部类{
}
}
}
方法(){
class 局部内部类{
}
}
{
class 局部内部类{
}
}
}
如何使用局部内部类
1.只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方
都不能使用该类
2.但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类
的父类或父接口类型
都不能使用该类
2.但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类
的父类或父接口类型
局部内部类的特点
1.内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但
是前面冠以外部类的类名和$符号,以及数字编号。
2.只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方
都不能使用该类。
3.局部内部类可以使用外部类的成员,包括私有的。
4.局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局
部变量的声明周期不同所致。
5.局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
6.局部内部类不能使用static修饰,因此也不能包含静态成员
是前面冠以外部类的类名和$符号,以及数字编号。
2.只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方
都不能使用该类。
3.局部内部类可以使用外部类的成员,包括私有的。
4.局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局
部变量的声明周期不同所致。
5.局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
6.局部内部类不能使用static修饰,因此也不能包含静态成员
匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一
个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或
实现一个类。
个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或
实现一个类。
格式:
new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}
new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}
匿名内部类的特点:
匿名内部类必须继承父类或实现接口
匿名内部类只能有一个对象
匿名内部类对象只能使用多态形式引用
匿名内部类必须继承父类或实现接口
匿名内部类只能有一个对象
匿名内部类对象只能使用多态形式引用
抽象类和抽象方法
超类声明一个方法但不提供实现,该方法的实现由子类提供。
这样的方法称为抽象方法。有一个或更多抽象方法的类称为抽象类。
这样的方法称为抽象方法。有一个或更多抽象方法的类称为抽象类。
用abstract关键字来修饰一个类,这个类叫做抽象类。
用abstract来修饰一个方法,该方法叫做抽象方法。
抽象方法:只有方法的声明,没有方法的实现。以分号结束:
比如:public abstract void talk();
抽象方法:只有方法的声明,没有方法的实现。以分号结束:
比如:public abstract void talk();
含有抽象方法的类必须被声明为抽象类。
抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重
写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍
为抽象类。
写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍
为抽象类。
不能用abstract修饰变量、代码块、构造器;
不能用abstract修饰私有方法、静态方法、final的方法、final的类。
对象
对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
实例化: 类名 对象名 = new 类名();
使用“对象名.对象成员”的方式访问对象成员(包括属性和方法)
在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。
(例外:static方法访问非static,编译不通过。)
(例外:static方法访问非static,编译不通过。)
在不同类中的访问机制:先创建要访问类的对象,再用对象访问类中
定义的成员。
定义的成员。
匿名对象:new 类名().方法
面向对象三大特性
封装性
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提
高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露
的暴露出来。这就是封装性的设计思想。
高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露
的暴露出来。这就是封装性的设计思想。
权限修饰符
继承
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,
那么多个类无需再定义这些属性和行为,只要继承那个类即可。子类通过extends关键字获取父类中的结构
那么多个类无需再定义这些属性和行为,只要继承那个类即可。子类通过extends关键字获取父类中的结构
使用方式:权限修饰符 class 子类名 extends 父类名{}
作用
继承的出现减少了代码冗余,提高了代码的复用性。
继承的出现,更有利于功能的扩展。
继承的出现让类与类之间产生了关系,提供了多态的前提。
注意:
子类继承了父类,就继承了父类的方法和属性。
在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和
方法。
方法。
在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,
而是对父类的“扩展”。
而是对父类的“扩展”。
继承的规则
子类不能直接访问父类中私有的(private)的成员变量和方法。
Java只支持单继承和多层继承,不允许多重继承
1.一个子类只能有一个父类
2.一个父类可以派生出多个子类
方法的重写:
定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称
为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
要求:
1.子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
2.子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
3.子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
子类不能重写父类中声明为private权限的方法
4.子类方法抛出的异常不能大于父类被重写方法的异常
注意
子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
多态
多态性,是面向对象中最重要的概念,在Java中的体现:
对象的多态性:父类的引用指向子类的对象
对象的多态性:父类的引用指向子类的对象
可以直接应用在抽象类和接口上
Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明
该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简
称:编译时,看左边;运行时,看右边。
该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简
称:编译时,看左边;运行时,看右边。
若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)
多态情况下,“看左边”:看的是父类的引用(父类中不具备子类特有的方法)“看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)
对象的多态 —在Java中,子类的对象可以替代父类的对象使用
一个变量只能有一种确定的数据类型
一个引用类型变量可能指向(引用)多种不同类型的对象
子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向
上转型(upcasting)。
上转型(upcasting)。
一个引用类型变量如果声明为父类的类型,但实际引用的是子类
对象,那么该变量就不能再访问子类中添加的属性和方法
对象,那么该变量就不能再访问子类中添加的属性和方法
方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
虚拟方法调用
正常的方法调用
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
e.getInfo();
Student e = new Student();
e.getInfo();
虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
e.getInfo(); //调用Student类的getInfo()方法
编译时类型和运行时类型:编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定
多态小结:
作用:提高了代码的通用性,常称作接口重用
前提:
1.需要存在继承或者实现关系
有方法的重写
成员方法:
编译时:要查看引用变量所声明的类中是否有所调用的方法。
运行时:调用实际new的对象所属的类中的重写方法。
成员变量:不具备多态性,只看引用变量所声明的类。
接口
接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都
要遵守。接口(interface)是抽象方法和常量值定义的集合
要遵守。接口(interface)是抽象方法和常量值定义的集合
接口的特点:
用interface来定义。
接口中的所有成员变量都默认是由public static final修饰的。
接口中的所有抽象方法都默认是由public abstract修饰的。
接口中没有构造器。
接口采用多继承机制。
接口定义举例
public interface Runner {
int ID = 1;//public static final可以省略
void start();//public abstract也可以省略
public void run();
void stop();
}
int ID = 1;//public static final可以省略
void start();//public abstract也可以省略
public void run();
void stop();
}
定义Java类的语法格式:先写extends,后写implements
class SubClass extends SuperClass implements InterfaceA{ }
class SubClass extends SuperClass implements InterfaceA{ }
一个类可以实现多个接口,接口也可以继承其它接口。
实现接口的类中必须提供接口中所有方法的具体实现内容,方可实
例化。否则,仍为抽象类。
例化。否则,仍为抽象类。
接口的主要用途就是被实现类实现。(面向接口编程)
与继承关系类似,接口与实现类之间存在多态性
接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,
接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义
(JDK7.0及之前),而没有变量和方法的实现。
接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义
(JDK7.0及之前),而没有变量和方法的实现。
接口和抽象类对比
Java新特性:
Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完
全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行
其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中
找到像Collection/Collections或者Path/Paths这样成对的接口和类。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。
我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认
方法。
全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行
其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中
找到像Collection/Collections或者Path/Paths这样成对的接口和类。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。
我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认
方法。
0 条评论
下一页
为你推荐
查看更多