=============类和对象 ======================
类:类是同一类事物的总称。
对象:现实世界中实实在在存在的事物。
类和对象的关系:类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体称为类。如鸟类有鸵鸟、大雁、麻雀等。鸵鸟、大雁、麻雀被称为鸟类的实体,即对象。
面向对象:对象所共有的功能和属性进行抽像,成为了类。客观事物在人脑中的主观反映。在程序里类是创建对象的模板。
面向对象程序设计的特点:封装性、继承性、多态性。
类成员:成员变量(属性)和成员方法(行为)。
定义成员方法的格式:权限修饰符 返回值类型 方法名(参数类型 参数名)
{方法体 return返回值} 成员方法需要返回值时使用关键字 return
java中的对象 :对现实对象的抽象(获得有用的,舍弃没用的)。
存储空间中的一块数据区域,用于存数据。如:人(nama sex age)
属性:实例变量(定义在类以内,方法之外)
1.默认的初值
2.实例变量的使用范围至少是类以内
3.实例变量调用必须有对象,实例变量和局部变量重名,局部优先。
例:
public class Test{
public static void main(String[] args){
//新建对象stu;stu存的是新建对象stu的地址。stu的专业术语:引用/对象变量/引用变量/实例变量
Student stu=new Student();
stu.name="tom"; //给对象stu的name属性赋值。
}}
class Student{ //用类声明的数据(str)为引用类型,如:Student str;
//实例变量:定义在方法之外,类以内的,没有static修饰的变量
//实例变量会有一个默认的初始值。初始值与变量定义时的类型有关。
//实例变量(成员变量)--->属性。可通过新建对象的引用来访问类的实例变量。如,stu.name;
String name;
int age;
String sex;
}
实例变量和局部变量的区别:
1,位置:局部变量定义在方法里面。实例变量定义在类以内方法之外。
2,使用的范围:局部变量只能在定义他的方法里面使用,直接调用变量名就可以了。
实例变量至少可以在定义他的整个类内使用,使用时必须用对象去调用。只有跟对象一起实例变量才有意义。
3,局部变量使用之前必须初始化。实例变量不需要赋初值,系统会给默认的初值。
4,局部变量在同一方法里不能重名。局部变量和实例变量可以重名,在方法里采用就近原则。
=================方法:=============
包括:
方法:
做什么:方法的定义
修饰符 返回类型 方法名(参数列表) 异常
怎么做:方法的实现 {******}
修饰符(如:public) 返回类型(如:int) 方法名/函数名(参数表--形参)
如:
public void eat(String fish){ //eat(),吃的功能。
//怎么做.
}
使用实例方法时也需要用对象去调用。如:stu.eat("fish");
======构造方法======
功能:创建其所属类型的一个新的对象。(构造方法无返回值类型)
语法格式:
< modifiers修饰符> <class_name类名>([< argu_list>]) {
[< statements>] 方法体
}
举例:
–class Person {
int age;
Person() { age = 18; }
Person(inti) { age = i; }
void setAge(inti) { age = i; }
–}
Java语言中,每个类都至少有一个构造方法;
如果类的定义者没有显式的定义任何构造方法,系统将自动提供一个默认的构造方法:
–默认构造方法没有参数
–默认构造方法没有方法体
Java类中,一旦类的定义者显式定义了一个或多个构造方法,系统将不在提供默认的构造方法;每个子类的构造方法里都有一个父类的默认构造方法,即super(),注意:前提是父类没有显示的构造方法,当父类有一个或多个显示构造方法时,子类的构造方法要想调用,必须在方法体第一行加上 super(参数类型)。
方法重载(overloading):编译时多态。
在一个类的内部,方法名相同形参数不同的方法,对返回类型不要求,这种现象称之为重载;
编译器会自动选择使用的方法。体现了一个编译时多态。
好处:对使用者屏蔽因为参数不同造成方法间的差异。
找方法时如果没有合适的,采取自动向上扩展原则。
调用时形参之间的区别一定要明确。
1. 形参的个数不同
2. 形参的类型不同
3. 形参的顺序不同
4. 形参的名字相同
方法覆盖(override):运行时多态。
1,发生在父类和子类之间
2,方法名相同,参数相同,返回类型相同
3,子类方法的访问权限不能更严格,只能等于或更加宽松。
构造方法:
1,没有返回类型,方法名必须和类同名。
2,构造方法不能手动调用,它只用在创建对象在时候,只出现在new之后。
只要构造方法被调用运行,就一定有对象产生。
3,在一个对象的生命周期里,构造方法只能被调用一次。
4,类写好后一定有构造方法,
如果程序没有显示的提供构造方法,JVM会提供一个默认的构造方法,public classname(){}
如果程序显示提供,系统不再提供默认的
5,同一个类的多个构造方法一定重载。
6,创建对象的同时构造方法的代码块里还可以写需要运行的代码,还可以给属性(实例变量)赋值,
引用类型的属性赋值就是用new创建对象,然后调用构造方法。如:Student stu=new Student();
用new创建对象时JVM做的三件事:
如:Student stu=new Student();
1,申请空间;(把值放到空间里,再把空间的地址给引用变量。)----创建父类对象
2,初始化实例变量;没显示声明值的话就用默认值。
3,执行构造方法,
因为实例变量在创建对象的过程中被初始化,所以使用实例变量前必须创建对象(要用对象去调用),否则实例变量根本不存在
=====关键字:this=======
1,在普通方法里,指代当前对象引用(哪个对象调用该方法,this就指向该对象)
2,this不能出现在静态方法里。
3,在构造方法里,this用来指代本类的其他构造方法。在本类构造方法之间互相调用。如:this(形参);
使用时放在构造方法里的第一行。
4,不能写成死循环(不能递归调用)
=====关键字:super=======
(和this的用法类似)
1,调用父类的构造方法,在子类调用父类的构造方法必须出现在第一句,构造方法第一句可能出现的三种情况(调用父类的构造方法看子类构造方法的第一句)①super();②super(参数)注意传递的参数一定是实体,有值的。③this(),先在本类的构造方法间调用,再看调用那个构造方法的第一句是什么
2,super访问父类的变量和方法,及super代表父类的对象,super.name;super.setName();
注意:this 和super关键字不能同时存在在方法体中。
======参数传递========
1,参数相当于局部变量
2,参数传递相当于赋值语句
3,基本类型数据传递的是本身的值,引用类型数据传递的是引用xx(Animal animal)(地址,对象变量本身的值)
面向对象的三大特性:
一,封装(Encapsulation):一个系统以合理的粒度出现。
定义:封装就是将客户端不应看到的信息包裹起来。使内部执行对外部来看不一种不透明的、是一个黑箱,客户端不
需要内部资源就能达到他的目的。(封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象
计算始于这个基本概
念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。)
1.事物的内部实现细节隐藏起来
2.对外提供一致的公共的接口――间接访问隐藏数据 3.可维护性
访问控制修饰符:public(公开的),protected(受保护的,1,本包内可见;2,其他包的子类可见)
default(默认,本包内可见),private(私有的,类内部可见)
访问控制修饰符 (可以范围) (可修饰)下面的类(指外部类)
private 本类 方法,属性
default 本包 类,方法,属性
protected 本包+子类 方法,属性
public 到处可见 类,方法,属性
1,属性:隐藏所有属性,用private。隐藏后属性只能在类以内访问 。程序可以根据需要提供get和set
2,方法(函数):该公开的公开,该私有的就私有。(视情况而定)
3,公开方法的功能,隐藏方法的实现细节。
二,继承(inheritance):抽象出不变性。
从一般到特殊的关系,可以设计成继承
特点:共性写在父类里面,特性写在子类
所有类的总父类是Object (Object是类的祖先)
父类里写的是共性,子类里写的是特性。
父类中用private修饰的属性和方法不能被子类继承;
但是父类里的属性子类都有,如果子类有特殊属性的话,就要在子类里定义
且在创建该子类对象的时候初始化属性(包括父类所有属性和该子类所有属性);
什么样的功能和属性可以继承到子类?
对于父类里的属性和方法,子类有权访问的,我们称为可以继承;
用new创建子类对象,JVM执行的过程:Dog d=new Dog(); 为d申请空间。class Dog extends Animal{}
(1)申请空间;(把值放到空间里,再把空间的地址给引用变量。)
(2)看本类构造方法的第一句
(3)默认的创建父类对象:
执行顺序:子类(2)---> 父类(2-->3-->4-->5)---> 子类(4-->5),
新建一个对象空间只申请一次(该空间存放所有父类和子类)。)
(4)初始化本类的实例变量(该类的所有属性);
(5)执行本类的构造方法,(构造方法只会在创建一个对象的时候被执行一次)
(创建是先执行父类的构造方法,在执行子类的构造方法,访问时先访问子类自己的特殊属性和方法再访问父类的属
性和方法)
用super调用父类被子类覆盖的普通方法和遮盖的属性
,
指代的是在创建子类对象过程中,由JVM自动创建的那个父类,如:super.方法名()/属性
用super调用父类的构造方法;必须出现在子类构造方法的第一句。如:super(形参);
1,在子类的构造方法里如果没有指明调用哪一个父类的构造方法(就是子类中没有super(形参)语句;),
JVM会默认调用父类的无参构造方法,跟本类构造方法的形参没有关系。
2,显示的写super,JVM会根据参数调用相应的父类构造方法。
3,有this(形参),在本类的构造方法之间调用,看被调用的那个构造方法的第一行。
三,多态(polymorphism):多态只有方法多态,没有属性多态。
用父类类型屏蔽子类之间的差异
所有的子类对象都可以当父类对象来用,一个父类型的引用可能指向的是一个子类对象,
如:把狗(对象)看作动物(类型)。Animal a=new Dog(); 编译看前面,运行看后面。
(编译时类型) (运行时类型)
1,运行时对象不会改变(对象是客观存在的),如:狗这个对象的属性和方法是不会改变的。
2,对一个引用,只能调用编译时类型里的已知方法。
如:编译器知道动物里已有的属性和方法,但不知道狗的属性和方法。
3,运行时会根据运行时类型自动寻找覆盖过的方法运行。
引用 instanceof 类名
instanceof是Java的一个二元操作符,和==,>,<是同一类东西。
由于它是由字母组成的,所以也是Java的保留关键字。
它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。
//结果为boolean值,
引用所指向的对象和类名类型是否一致(对象是否属于类名类型)
类型的转换:转换编译时类型
Sub su= (Sub) s;
子类型的引用向父类型转换时,不需要强转
父类型的引用向子类型转换时,需要强转
Animal a=new Cat();
Dog d=(Dog)a; // 类型转换异常
引用 instanceof 类名 -----> boolean
引用所指向的对象和类名所代表的类型是否一致
a instanceof Animal -----> true a instanceof Cat----------> true a instanceof Dog----------->false
Employee e=new Manager();
e instanceof Employee ------>true
e instanceof Manager------> true
属性没有多态,属性只看编译时类型
编写程序的顺序:
class 类名{
private属性(有什么)
无参的构造方法(public类名(){})
有参的构造方法(作用:给属性赋值)
set和get(设置和获得属性)
业务方法(做什么)
}
一,修饰符:static
static变量:如:static int index=2;
类的所有对象共同拥有的一个属性;可以用类名直接访问,又称为类变量,
类的所有对象共同拥有的一个变量;类第一次被加载时会初始化静态变量
(也就是会先执行static修饰的变量);
跟类创建了多少对象无关;任何对象对静态变量做的修改,其他对象看到的是修改后的值。
可以用作计数器,记录类创建对象的个数, static变量在类加载的时候只会被初始化一次,
static方法:如:public static void teach(){}
可以用类名直接去调用,不需要对象所以不能直接访问(在没有对象的情况下)实例变量,
在静态方法里不能出现this和super,类的所有对象共同拥有的一个方法;跟类创建了多少
对象无关。
在继承里,父类的静态方法只能被子类的静态方法覆盖,且覆盖以后没有多态
(访问的是父类的静态方法);
static初始化块:如:class Teacher(){
static int index=4;
static{ //static初始化块
.........
}
}
静态初始化块:用static修饰类里面的一个独立的代码块,类第一次被JVM加载的时候执行,只
被执行一次。
类加载:JVM在第一次使用一个类时,会到classpath所指定的路径去找这个类所对应的字节码文件,
并读进JVM保存起来,这个过程称之为类加载,一个线程一个jvm。
二,final (最后的,最终的)final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承
final类:如:final class Animal{}
表示该类不能被继承,意味着不能改变里面的代码;
对虚拟机的正常运行有重要作用的类通常用final修饰,如:String,System,Math ...等类
final方法:如:public final void sleep(){} 该方法不能被覆盖(修改),但能被子类访问。
final变量:如:final (static) int index=4;
该变量是常量能被继承(访问);
final修饰的变量就是常量,通常和static一起连用,来声明常量;
final修饰引用类型数据,指的是引用(地址)不能变,但引用里的数据不受限制。
final修饰的变量,只要在初始化的过程中就可以赋值。
实例变量:声明的同时或构造方法里赋值;
静态变量:声明的同时或在静态代码块里赋值;
三,abstract
abstract类:如:abstract class Animal{}
抽象类,不能创建对象(如一些父类),但是可以声明一个抽象类型的引用
(可以声明父类类型子类对象,编译时利用多态调用抽象方法)。
含有抽象方法的类一定是抽象类,但抽象类并不一定要有抽象方法;
抽象类一般是用来被继承的;子类继承自抽象类,就要实现里面的抽象方法,
如果不想让子类也是抽象类的话,必须实现父类里面所有的抽象方法。
抽象类有构造方法,有父类,也遵循单继承的规律。
abstract方法:如:public abstract void sleep();
抽象方法,只有方法名的定义,没有实现体(只定义了能做什么,没定义怎么做),不能被调用,
用于被子类的方法覆盖或重新实现。只能放在抽象类中。
好处:允许方法的定义和实现分开。
public protected default private static final abstract
可以: public static
private static
public final
public static final
不可以:abstract final void eat();
private abstract void eat();
static abstract void eat();
abstract不能和final,private,static连用。
四,interface:是抽象类的变体,。在接口中,所有方法都是抽象的。如:interface M{
int num=3;
void eat();
}
理解为接口是一个特殊的抽象类,所以接口不能创建对象,且接口没有构造方法,
但可以声明一个接口类型的引用(m是接口类型实现类对象,如:M m=new N();)
接口存在的意义是被子类实现,如果不想让子类也抽象,
就要实现接口里面所有的抽象方法,实现过程中注意访问权限;
用 implements 关键字实现接口,如:class N implements M{
public void eat(){...}
}
接口里面的常量默认都是public static final的;
接口里面的方法默认都是public abstract的。
接口本身支持多继承,继承了父接口里功能的定义,如,interface A extends B,C,D{} //A,B,C,D都是接口;
类可以同时继承一个父类和实现接口(或多个接口)。
如:class AA extends BB implements CC,DD,EE{}//AA,BB 是类,CC,DD,EE是接口;
作用:1,用接口去实现多继承,接口是对类的共性进行再次抽象,抽象出类的次要类型。
如:蜘蛛侠,拥有人和蜘蛛的属性,但主要类型是人,次要类型(接口)是蜘蛛,
因为接口是次要类型,所以在类关系里不占一个节点,不会破坏类层次关系的树状结构,
2,标准(保证弱耦合):一个接口就是一个标准(里面的属性不能改变,只定义了功能,
但没有被实现), 接口将标准的制定者,标准的实现者以及标准的使用者分离开,
降低实现者和使用者的耦合。接口是java里一种重要的降低耦合的工具;
接口可以屏蔽不同实现类的差异,
当底层的实现类更换后,不会对上层的使用者产生影响,体现在参数和返回值。
写程序时,应该先写实现者再写使用者,如:Bank.java是实现者,View.java是使用者,
但是有了接口之后,就可以用接口回调的功能;
接口回调:先定义接口,然后写使用者和实现者的顺序随便(一般是先写使用者,
后写实现者);利用参数把实现者传给使用者(即:实现者是使用者的属性),
使用者利用接口调用实现者相应的功能。
**接口和抽象类的区别1一个类可以implements多个接口,而只能extends一个抽象类
2,一个抽象类可以实现部分的方法,而接口都是抽象的方法和属性
Object是Java里所有类的直接或间接父类,Object类里面的所有功能是所有java类共有的
1,JVM调用垃圾回收器回收不用的内存(没有引用指向的对象)前运行finalize(),给JVM用的方法。
程序显示的通知JVM回收没用的内存(但不一定马上就回收):System.gc();或 Runtime.getRuntime().gc();
2,toString()返回对象的字符串表现形式,打印对象时,虚拟机会自动调用toString获取对象的字符串表现格式,
如:System.out.println(str.toString()); ==System.out.println(str);
如果本类不提供(覆盖)toString(),那么使用的是Object类里的相应方法,打印的就是地址。
如:public String toString(){
return ".....";
}
3,基本类型时“==“判断变量本身的值是否相等;引用类型时,判断的是地址是否相等。
equals判断的是对象内容是否相等。对于自己创建的类,应该覆盖Object类的equals()方法;
否则使用的是Object类里的equals()方法,比的是地址。
覆盖方法如下:
/*****************************************************
public boolean equals(Object o){
if(o==null) return false;
if(o==this) return true;
if(!(o.getClass()==this.getClass())) return false;
final Student s=(Student)o;
return this.name.equals(s.name) && this.age==s.age ; //比较原则;
}
******************************************************/
覆盖euqals()方法时遵循的原则:
自反性:a.quals(a); //true
对称性:a.equals(b);<==> b.equals(a); //true
传递性:a.equals(b);//true b.equals(c); //true
--->则:a.equals(c); //为true
封装类(Wrapper class):
OverLoading时,基本类型时采用向上匹配原则,
如果没有基本类型的话就向包装类转换,如果还没有就让这个基本类型在包装类里也采用向上匹配原则;
基本类型-转换到-->包装类
boolean----->Boolean
int-------->Integer //Integer是引用类型,
int-------->Ddouble //合法, 但Integer------>Double 非法
double------>Double
...... -------> ......
任何类型----->Object
基本数据类型int可以向double自动扩展,但是包装类型之间不能自动的相互转换,
基本类型数据--->包装类型
int i=3;
Integer it=new Integer(i); //手动转换;基本类型向包装类型转换。
int <----> Integer <----> String
转换时String类型必须为全数字字符串。如:"2515" 不能为:"abc265","aec"...等
String str=”123”; int it=Integer,parseInt(str);把字符串转换成数字。String str2=it+“”;把数字转化成字符串
==内部类============
定义在其他代码块(类体或者方法体)里的类称为内部类;
编译后每一个内部类都会有自己的独立的字节码文件,
文件名:Outer$Inner.class-->内部类也可以有父类和实现接口。也可以有抽象方法。
根本位置和修饰符的不同分为四种:
1,member inner class 成员内部类,当实例方法或变量一样理解。
1)定义的位置:类以内,方法之外,没有静态修饰符(static)。
2)本身能定义的属性和方法:只能定义非静态的属性和方法。
3)能直接访问的什么:能访问外部类的所有静态和非静态的属性或方法。
4)怎么创建对象:在外部类内的方法内:Outer.Inner inner=new Outer().new Inner();
在外部类外的类的方法内:Outer.Inner inner=new Outer().new Inner();或
在Outer类里提供一个getInner()方法,返回内部类的对象,这样在外部类外的类的方法内也可以用该成员内部类。
2,static inner class 静态内部类(嵌套内部类),当静态方法或变量一样理解。
static只能修饰内部类,不能修饰外部类。
1)定义的位置:类以内,方法之外,有静态修饰符(static)。一般写在外部类的属性下面。
2)本身能定义的属性和方法:可以定义静态和非静态的属性或方法。
3)能直接访问的什么:只能访问外部类的静态属性和方法。
4)怎么创建对象:在外部类内的方法里: Outer.Inner inner=new Outer.Inner();
在外部类外的类方法里: Outer.Inner inner=new Outer.Inner();
3,local inner class 局部内部类 当局部变量一样理解。
1)定义的位置:方法里面的类,前面不能用public或static修饰。
2)本身能定义的属性和方法:只能定义非静态的属性和方法。
3)能直接访问的什么:能访问方法内用final修饰的局部变量(不能与该类内的变量名相同)。
能访问外部类的所有静态和非静态的属性或方法。
4)怎么创建对象:只能在方法内创建对象,如:Inner inner=new Inner(); 对象的作用范围只在方法内。
4,annonymous inner class 匿名内部类 如: Teacher tc=new Teacher(){
1)没有名字的类,没有构造方法。是一个特殊的局部内部类, public void teach(){...}
可以实现一个接口, 或者一个类, }
生命周期里只能产生一个对象(tc),也就是说只能被一个对象(tc)调用,
2)除了没有名字外,看匿名内部类所在的位置,他的定义和访问将和成员内部类、静态内部类、局部内部类一样。
一般像局部内部类的定义和访问比较多。
3)当试图创建接口或者抽象类对象的时候,用匿名内部类。
表示类体的{...}紧跟在抽象实例(接口)之后,表示实现该抽象实例(接口)。
调用匿名内部类的方法只能用写类时创建的那个对象(tc)。
作用:1,不破坏访问权限的情况下,内部类可以使用外部类的私有成员变量和方法。
2,将接口公开,将实现类(实现公开的接口)作成内部类隐藏起来,强制要求使用者使用接口,强制降低偶合度。
3,Java通过接口和内部类两种机制来实现多继承。在类内部可以建立本类的实例,然后调用本类内的其他方法。
转载于:https://blog.51cto.com/10298199/1659454