1.面向对象编程规范
(C++、Java、Go)–能进行现实生活的抽象
- 面向过程编程规范(C语言)
- 面向切面编程(EE-AOP)
- 面向接口编程-接口优先原则
- 函数式编程-Scala(JVM)
每个对象-----类
属性以及方法
OOA:面向对象分析
OOP:面向对象编程
OOD:面向对象设计
1.1面向对象三大特征:
a. 封装性:将客观事物封装成为抽象的类,每个类都有自己的属性与方法,并且类可以让自己的数据与方法只让可信的类或对象操作,对不可信的进行信息隐藏。内部操作对外部操作而言不可见(保护性)
b. 继承性:可以使用现有类的所有功能,并且在无需重新编写原有类代码的情况下进行功能上的扩展。
c. 多态性:指的是一个类实例的相同方法在不同情形下有不同的表现形式。多态机制使得具有不同内部结构的对象可以共享相同的外部接口。(利用多台可以得到良好的设计)
1.2Java中类与对象的的定义与使用
类是一个共性的概念,而对象是一个具体的、可以使用的事物。
类是生产对象的蓝图,先有类才可以产生对象。对象的所有属性和行为,一定在类中进行了完整的定义。
class 类名称{
属性1;
属性2;
. . .
方法1(){ }
方法2(){ }
. . .
}
类中的属性与方法(不带static关键字的)只能通过对象调用
对象产生语法:
类名称 对象名称 = new 类名称();
对象内存分析:
栈内存(虚拟机局部变量表):存放的是局部变量
(各种基本数据类型、对象引用-----对象名字)
堆内存:保存对象。
new 表示在堆上新分配空间
立即空间:没有任何内存指向的堆内存空间
2.private实现封装处理
private不能用于外部类的的定义,可用于内部类。
将属性、方法用private封装后表示,被封装的属性与方法只能在本类中上使用,类外部不可见。
此时要想访问被封装的属性,必须提供getter与setter方法
setter方法:主要进行属性内容的上设置与修改;
getter方法:主要进行属性内容的取得。
类的设计原则:编写类的时候,没有额外说明,所有属性必须使用private封装 (成员变量)
3.构造方法(类中属性初始化)
3.1构造方法三大特征
a. 构造方法名称必须与类名称相同。
b. 构造方法没有返回值类型声明,但是可以单独写return语句来作为方法的结束。
c. 每个类中一定至少存在一个构造方法,如果没有明确定义,系统会自动生成无参构造,若在类中自定义了构造方法,则系统不在默认生成无参构造。
3.2构造方法重载
构造方法重载:参数个数不同。
与普通方法不同,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。
3.3类定义顺序:
(1).定义属性—>(2). 定义构造方法---->(3). 定义普通方法
4.this 关键字
4.1 表示调用本类属性
只要在类中访问类的属性一定要加上this关键字
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
4.2表示调用本类方法
a. 调用普通方法
this. 方法名(参数)
public Person(String name,int age){
this.name = name ;
this.age = age ;
this.print();//调用普通方法
}
当有类的继承关系时,表示本类方法一定要加上this关键字
b.调用构造方法
this(参数)
public Person(){
System.out.println("********");
}
public Person(String name){
this();//调用本类无参构造
this.name = name ;
}
public Person(String name,int age){
this(name);//调用本类有参构造
this.age = age ;
}
- 只能在构造方法中使用this调用其他的构造方法。
- this调用构造方法必须在构造方法首行 ,且只能出现一次。
- this调用构造方法不允许成环 this调用构造方法不允许成环
4.3表示当前对象
class Person{
public void Print(){
System.out.println("Persion类中的print的方法: "+this);
}
}
public class Test{
public static void main(String[] args) {
Person per1 = new Person();
System.out.println("main方法: "+per1);
per1.Print(); //this的当前对象是per1
System.out.println("***********************");
Person per2 = new Person();
System.out.println("main方法: "+per2);
per2.Print(); //this的当前对象是per2
}
}
输出:
5.static 关键字
-
static 只能用于修饰成员变量,不能用于修饰局部变量。
-
在一个静态方法中只能访问用static修饰的成员,没有被static修饰的成员需要先创建对象才能访问。
5.1 static 变量–类属性(静态属性)
static 属性成为类属性,保存在全局数据区中(方法区–所有对象共享区域),通过类名调用,与对象实例化无关。
描述共享属性使用static属性(%1 比例)。
5.2 static 方法–类方法(静态方法)
静态方法不需要创建对象就可以调用。
通过类名调用,与对象实例化无关,常见于工具类方法。
局部变量不能用static修饰。
结论:static与private 均不能加在外部类之上,内部类可以。
6.代码块的定义与使用
根据代码块出现的位置以及关键字,分为以下四种代码块
6.1 普通代码块
定义在方法中的代码块
6.2 构造块**
定义在类中的代码块(不加任何修饰符)
在对象产生时,优先于代码块执行,有几个对象产生,就调用几次构造块。
用于在构造方法执行前完成一些属性的初始化操作。
6.3 静态代码块
I. 非主类中的静态代码块
在类加载时执行(什么时候用到这个类),优先于构造块执行,无论有多少对象产生,只会调用一次。
执行顺序:静态代码块(只调用第一次)------>构造块(有几个对象产生,就调用几次构造块)------>代码块
II. 主类中的静态代码块
主类中的静态块优先于主方法执行。
阿里面试题分析:
class A {
//构造方法
public A(){
System.out.println("1.Hello A!父类构造方法");
}
//非静态代码块
{
System.out.println("2.i'm A class.父类非静态代码块");
}
//静态代码块
static{
System.out.println("3.static A 父类静态代码块");
}
}
public class B extends A {
//构造方法
public B(){
System.out.println("4.Hello B! 构造方法");
}
//非静态代码块
{
System.out.println("5.i'm B class.非静态代码块");
}
//静态代码块
static{
System.out.println("6.static B 静态代码块");
}
public static void main(String[] args) {
System.out.println("7.---start---");
new B();
new B();
System.out.println("8.---end---");
}
// 36 7 2154 2154 8
}
输出:
6.4 同步代码块
(多线程同步部分再议)
7.继承的定义与使用
7.1 在已有基础上进行功能上的扩充(可重用)
判断两个类之间能否使用继承:
student is a Persion
Java中类继承使用extends关键字
子类(派生类)
父类(超类 / 基类)
7.2继承的限制
I. 子类对象实例化前首先调用父类构造方法产生父类对象后再调用子类构造方法实例化对象。
II. Java只允许单继承,不允许多继承。(Java的单继承局限)
要想在Java中实现类似的“多继承”,要么多层继承(多层继承:即一个类可以再去继承其他等我父类),要不使用内部类。
III.多个类可以继承一个父类。
IV. 在继承是,子类会继承所有结构。(包含私域与其他属性,方法)
显式继承:所有非私有操作属于显式继承(可以直接调用)
隐式继承:所有私有操作属于隐式继承(不可以直接调用,需要通过其他形式调用)
8.覆写(重写)–override
定义:如果子类定义了覆类完全相同(不算权限)的方法或者属性的时候,这样的操作就称为覆写。
8.1 方法的覆写
定义:子类定义了与父类方法名称, 参数列表, 返回值类型完全相同的方法。被覆写的不能拥有比父类更为严格的访问控制权限。
判断调用的到底是父类方法还是子类方法:
a. 看new 在哪儿(当前使用的对象是通过哪个类new 的)
b. 调用的方法有没有被子类覆写,如果被覆写,调用的一定是被覆写后的方法。
private < defallt(啥也不写的时候表示是defallt)-包的访问权限< public
方法覆写不能出现private关键字。(隐式继承:子类不能调用父类)
8.2.属性的覆写(了解)
当子类定义了和父类属性名称完全相同的属性的时候,就成为属性的覆盖。
8.3 方法重载与方法覆写(重写)的区别:
a.概念上:重载的方法名称相同,参数类型及个数不同;覆写的方法名称、返回值类型及个数完全相同。
b.范围:重载在同一个类里;覆写存在继承关系。
c.权限要求:重载没有权限要求;被覆写的方法不能拥有比父类更为严格的访问权限。
9.super关键字
9.1. super用于方法
I. 用于构造方法
- 当子类调用无参构造时,super可写可不写,表示调用父类无参构造
- 当子类调用有参构造时,super(参数列表),必须写,告诉编译器当前调用的是哪个有参构造。当子类调用有参构造时,super(参数列表),必须写,告诉编译器当前调用的是哪个有参构造。
(1)子类构造方法中调用父类构造必须是第一行语句。
(2)this与super不能同事调用。
II.用于普通方法
super . 方法名(参数);
用于在子类中明确调用父类被覆写的方法。
9.2. super用于属性(了解)
super.属性名
表示调用父类中被覆写的属性(权限不是private)。
10.final 关键字–终结器
10.1 final修饰类
(Sting类以及8大基本数据类的包装类,Integer)
当一个类被final修饰,表示改类不能拥有子类(该类不允许被继承)。
一旦一个类被final修饰,改类中的所有方法都会默认加上final(成员变量不会加final)
10.2 final修饰方法
当一个类被final修饰,明确表示该方法不能被覆写。
当一个方法被private修饰后,相当于加了一个final关键字。
10.3 final修饰属性–常量
I. final修饰普通类型的成员变量(最主要用途)。
- 被final修饰的成员变量必须在声明初始化(也可以在构造块或构造方法中初始化),并且初始化后值无法被修改。
- final 变量 ----final 变量 -常量(值不能改变,没给我对象都有自己的final变量,在对象产生时初始化)
- static final ----static final -全局变量(所有对象共享此变量,并且在类加在时初始化,效率较高,通过类名调用)
- 全局变量命名规则:多个单词全大写,单词间 _ 分隔。全局变量命名规则:多个单词全大写,单词间 _ 分隔。
II. final修饰引用数据类型变量(值不能改变)
11.多态
向上转型(90%):
用于参数统一化
父类 父类对象 = new 子类();(自动)
对象的向上转型有一个最为核心的用途:操作参数统一。
向下转型(1%):
当父类引用需要调用子类扩充方法时,才需要向下转型。
子类 子类引用 = (子类)父类引用;(强转)
要发生向下转型,必须先发生向上转型(认爹)。否则,会报ClassCastException异常。
运行时异常:ClassCastException(类型转换异常)。
引用名 instanceof 类:boolean 表示改引用是否能表示该类实例。
12.内部类定义与使用
在类内部进行其他类操作结构嵌套操作
存在私有内部类(静态、成员均可)
ArrayList 中Mode内部类,HashMap中Entry内部类(私有内部类)
12.1内部类的优点
- 内部类与外部类可以方便的访问彼此的私有域(包含私有方法,私有属性)
- 内部类是一种封装(保护性),对外部的其他类隐藏(心脏包在人体内部)
- 内部类可以实现java单继承的局限
12.2内部类与外部类的关系
- 对于非静态内部类,内部类的创建需要依赖类对象,在没有外部类实例之前无法创建非静态内部类。
- 内部类是一个相对独立的个体,与外部类没有is-a关系。
- 内部类直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的间接访问引用
12.3创建内部类语法(在外部类外部)
I. 创建非静态内部类
外部类 . 内部类 内壁类引用 = new 外部类().new 内部类();
Outter . Inner in= new Outter( ).new Inner( );
II. 创建静态内部类
外部类 . 内部类 内壁类引用 = new 外部类().内部类();
Outter . Inner in= new Outter( ).Inner( );
12.4内部类分类:
I. 成员内部类(成员方法)—成员内部类不能拥有静态域,但可以访问外部静态域
a. 成员内部类不能存在任何static变量或方法。
b. 成员内部类是依附外部类,所以只有创建了外部类才能创建内部类。
外部类 . 内部类 内壁类引用 = new 外部类().内部类();
Outter . Inner in= new Outter( ).new Inner( );
II. 静态内部类(静态方法)—静态内部类不能访问外部静态域,但可以拥有静态域,
a. 静态内部类的创建不需要依赖外部类,可以直接创建
b. 静态内部类不可以使用任何外部类的非static域(包含属性与方法),但可以存在自己的成员变量。
外部类 . 内部类 内壁类引用 = new 外部类().内部类();
Outter . Inner in= new Outter( ).Inner( );
III. 方法内部类
a. 方法内部类不允许使用访问权限修饰符 public 、private、 protected 均不允许
b. 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问。
c. 方法内部类如果要想使用方法形参,改形参必须使用final声明(JDK8经形参变为隐式final)
IV. 匿名内部类(lamdba表达式前身)
new 父类(参数列表) 或 父接口(){ //匿名内部类实现部分 }
匿名内部类就是一个没有名字的方法内部类。因此特点与方法每部类完全一样,除此之外,还有两个自己的特点:
a. 匿名内部类必须继承一个抽象类或者实现一个接口。
b. 匿名内部类没有构造方法,因为它没有类名。