JAVA面向对象
封装
封装是面向对象程序设计的核心思想,它是指将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其细节,这就是封装的思想。
继承
继承是面向对象程序设计提高重用性的重要性。它体现了特殊类与一般类之间的关系,当前特殊类包含一般类的所有属性和行为,并且特殊类还可以有自己的属性和行为时,称作为特殊类继承了一般类。一般类又称为父类或者基类,特殊类又称子类或派生类。
多态
多态是面向对象程序设计的重要特征。程序中的多态是指一种行为对应着多种不同的实现。
类的定义
在类中,属性是通过成员变量体现的,而行为是通过成员函数(又称为方法)实现的
类实际上就是封装对象属性和行为的载体,而对象是类抽象出来的实例
Java中定义类的通用格式:
x1
2class 类名{3 属性类型 成员变量名; //成员变量(对象属性)4 ...5 修饰符 返回值类型 方法名([参数列表]){ //成员方法(对象行为)6 7 //方法体8 return 返回值;9 10 }11}示例定义一个类:
xxxxxxxxxx161
2class TextOne{3 4 //定义属性:5 String name="李白";6 int age=18;7 String adrss="大唐不夜城";8 String work="诗人";9 10// 定义方法:11 public void say(){12 System.out.println("十步杀一人");13 System.out.println("千里不留行");14 15 }16}对象的创建和使用
类是对象的抽象,对对象定义了属性和行为,但类本省既不带任何数据,也不存在内部空间里面,而对象是一个具体的存在,既有独立的内存空间,又有独特的属性和行为,属性还可以根据自身的行为而发生改变。
声明对象:
类名 对象名;
类是自定义类型,也是一种引用类型,因此对象名是一个引用变量,默认值为null,表示不指向任何堆内存空间,需要对该变量进行初始化,Java使用new关键字来创建对象,也称为实例化对象
实例化对象:
对象名 = new 类名();
声明和实例化对象可以简化成一条语句:
类名 对象名 = new 类名();
xxxxxxxxxx11TextOne te=new TextOne();类的封装
封装是面向对象的三大特征之一,类的设计者将类设计成一个黑匣子,使用者只能通过类所提供的共公方法来实现对内部成员的操作和访问,而不是看见方法的细节,也不能直接访问对象的内部成员。
类的封装可以隐藏类的实现细节,迫使用户通过方法去访问数据,这样就可以增强程序的安全性。
为了避免使用程序时出现不合理的情况,就需要用到封装,即不让使用者访问类的内部成员。
在定义类时可以将类中的属性私有化,这样外界就不可以随意访问了。
在Java中使用private关键字来修饰属性,是由属性只能在本类中被访问。
private关键字
定义了类内部的成员的私有化,这样类的属性只能在本类中使用,外界不能随意访问。
xxxxxxxxxx141
2class Parent{3 //私有化成员变量,外界不能随意访问4 private String name="libai";5 private String adrss="BeiJin";6 private int age=18;7}8class textTwo{9 public static void main(String[] args){10 //实例化Parent对象11 Parent p=new Parent();12 System.out.println(p.name);13 }14}编译时程序会报错:”Parent name is not visible”等
出现错误的原因在于:对象不能直接访问私有属性,这样可以保证对象无法直接去访问类中的属性,从而保证了入口处有所限制。
但这样做使得所有的属性都不能被外界访问了,为了让外界使用者访问类中的私有属性,需要提供public关键字修饰的属性访问器,即使用设置属性的setXxx()方法和获取属性的getXxx()方法。
xxxxxxxxxx151
2class Parent{3 private String name;4
5 //设置属性方法6 public void setName(String name){7 this.name=name;8 }9 10 //获得属性方法11 public String getName(){12 return name;13 }14
15}其中,setName()设置属性name的属性值,getName()获取name属性的属性值。
访问修饰符
Java中访问修饰符也叫访问控制符,是指能够控制类、成员变量、方法的使用权限的关键字,通常放在语句的最前端,在面向对象的编程中,访问控制符是一个很重要的概念,可以使用它来保护对类、变量、方法和构造方法的访问。
类的修饰符:
类的修饰符只有一个——public
属性和方法的修饰符:
属性和方法的修饰符有四个——public、private、protected,还有一种默认权限(default)
公有访问控制符
公有,即对所有类可见。关键字——public,被public声明的类、方法和接口允许被程序中的任何类访问。
Java的类是通过包的概念来组织的。包是类的一个松散的集合,处于同一包中的类可以不需要任何声明方便地相互访问和引用,而对于不同包中的类则需要导入相应的public类所在的包。
由于类的及继承性,类中的所有公有方法和变量能被其子类继承。
每个Java的主类必须有public修饰,否则Java解析器不能运行该类。
私有访问控制符
私有的,即在同一类中可见,使用关键字——private。被private修饰的方法和属性被提供更高的保护,只能由类自身访问或者修饰,而不能被其他类(包括本类的子类)来获取和引用。
保护访问控制符
受保护的,即对同一类内可见,使用关键字——protected。protected可以修饰属性的方法,不能修饰类。protected修饰的成员变量可以被3种类引用:1. 该类本身;2. 与它同在一个包中的其他类;3. 在其他包中该类的子类。
使用protected修饰的主要目的是允许其他包中该类的子类来访问父类的特定属性。
默认访问控制符
默认访问权限规定,该类只能被同一个包中的类访问和引用,而不可以被其他包中的类使用,这种访问特性又称包访问性。也就是说,类内的变量或者方法如果没有访问控制符修饰,就具有包访问性。简单说,定义在同一个程序中的所有类属于一个包。
总结:按访问范围由大到下
public>protected>默认>private
构造方法
构造方法是类中一个特殊的成员方法,可以改变默认的初始化,让系统创建对象时就为该对象的成员属性显式地指定初始值。
构造方法的定义
构造方法是使用new关键字创建一个对象时被调用的。
构造方法的三个特征:
构造方法名与类名相同
构造方法没有返回值类型
构造方法中不能使用return返回一个值
定义一个构造方法:
xxxxxxxxxx121class Text{2 //构造方法3 public Text(){4 System.out.println("look,there is a little boy!");5 }6}7public TextPage{8 public static void main(String[] args){9 Text t=new Text();10 //运行程序直接打印look,there is a little boy!11 }12}构造方法在实例化对象时就直接调用这个方法
构造方法的重载
由于系统提供的默认构造方法通常不能满足需求,这时就需要多个构造方法,与普通方法不同,只要每一个构造方法的参数列表不同就可以实现重载,这样在创建对象时,就可以通过调用不同的构造方法为不同的属性赋值。
xxxxxxxxxx221
2class TextTwo{3 private String name="李白";4 private int age=18;5 private boolean What=true;6 //三个不同参数的构造方法7 //构造方法的重载8 public TextTwo(String name){9 System.out.println(name);10 }11 public TextTwo(int age){12 System.out.println(age);13 }14 public TextTwo(boolean what){15 System.out.println(what);16 }17}18public class What{19 public static void main(String[] aegs){20 TextTwo t=new TextTwo();21 }22}
this关键字
类在定义成员变量时,局部变量和成员变量可以重名,但此时不能访问成员变量,为了避免这种情况,Java提供了this关键字,表示当前对象,指向调用对象本身。
xxxxxxxxxx211public class one {2
3 public static void main(String[] args) {4 pp ps=new pp();5 pp pss=new pp();6 ps.a(ps);7 ps.a(pss);8 }9}10class pp{11 public void a(pp p){12 System.out.println(this);13 System.out.println(p);14 if(this==p){15 System.out.println(true);16 }else{17 System.out.println(false);18 }19 }20}21

this就是调用对象本身
使用this调用类中的属性
this关键字可以明确调用类中的成员变量,不会与局部变量名发生冲突
xxxxxxxxxx171
2class Person{3 private String name;4 public Person(String name){5 this.name=name;6 }7 public void say(){8 System.out.println(name);9 }10}11public class Text{12 public static void main(String[] args){13 Person p=new Person("LiBai");14 p.say();15 //LiBai16 }17}使用this明确调用了成员变量,避免了与局部变量产生冲突
使用this调用成员方法
this既然可以访问成员变量,那么也可以访问成员方法
xxxxxxxxxx151
2public class TextOnew{3 public static void main(String[] args) {4 Text t=new Text();5 }6}7
8class Text{9 public Text(){10 this.hi();//在构造方法里面调用hi()方法11 }12 public void hi(){13 System.out.println("help me!");14 }15}使用this调用构造方法
构造方法是创建对象时自动调用的,因此不能直接像调用成员方法那样调用构造方法,可以使用this([实参列表])的方式调用其他的构造方法
xxxxxxxxxx171
2public class TextOnew{3 public static void main(String[] args) {4 Text t=new Text("LIBAI");5 6 }7}8
9class Text{10 public Text(){11 System.out.println("我是你爹");12 }13 public Text(String name){14 this();//调用无参构造函数15 System.out.println(name+",我是你爹!");16 }17}需要注意的是,使用this()调用构造方法时,this()必须位于构造方法语句的首行
另外,this调用构造方法时,一定要预留一个构造方法作为出口,一般将无参构造方法作为出口,即在无参构造中不再去调用其他构造方法
static关键字
使用static关键字修饰的成员变量,称之为静态变量或者类变量,它被类的所有对象共享,属于整个类所有,因此可以通过类名直接访问,而未使用static的成员变量称为实例变量,它属于具体的对象独有,只能通过引用对象访问。
xxxxxxxxxx171
2class T{3 int count;4 public t(){5 count++;6 }7}8public class tt{9 public static void main(String[] aegs){10 T t1=new t();11 T t2=new t();12 T t3=new t();13 T t4=new t();14 T t5=new t();15 System.out.println(t5);//打印的值为116 }17}xxxxxxxxxx171
2class T{3 static int count;4 public t(){5 count++;6 }7}8public class tt{9 public static void main(String[] aegs){10 T t1=new t();11 T t2=new t();12 T t3=new t();13 T t4=new t();14 T t5=new t();15 System.out.println(t5);//打印的值为5,每实例化依次对象count的值就加1,每创建一个对象就会调用一次构造方法,所以由static修饰的成员变量被所有对象共享16 }17}
需要注意的是,static只能修饰类中的成员变量,不能修饰方法中的局部变量
静态方法
使用static修饰的成员方法称为静态方法,无须创建类的实例就能调用静态方法,静态方法可以通过类名调用。
xxxxxxxxxx131
2class t{3 //创建一个静态方法4 public static void say(){5 System.out.println("what is your qq number?");6 }7}8public class tt{9 public static void main(String[] args){10 //直接就可以调用静态方法11 t.say();12 }13}代码块
分类:
静态代码块
普通代码块
构造代码块
同步代码块
普通代码块
普通代码块是写在方法名后或者方法体内的使用{}括起来的一段代码:
xxxxxxxxxx101
2public class t{3 public static void main(String[] args){4 //普通代码块5 {6 int x=100;7 System.out.println(x);8 }9 }10}构造代码块
构造代码块是直接定义在类中的代码块,它没有任何的前缀、后缀和关键字,构造代码块也和构造方法一样在创建对象时被自动调用
xxxxxxxxxx161
2class t{3 public t(){4 System.out.println("这是构造方法");5 }6 //构造代码块7 {8 System.out.println("这是构造代码块");9 10 }11}12public class tt{13 public static void main(String[] args){14 t tt=new t();15 }16}注意:构造代码块中的代码会优先于构造方法中的代码执行,而且每次实例化对象都会执行
静态代码块
静态代码块是使用static关键字修饰的代码块,它是最早执行的代码
xxxxxxxxxx141class TT{2 public TT(){3 int a=18;4 }5 //静态代码块6 static{7 System.out.println("这是静态代码块");8 }9}10public class tt{11 public static void main(String[] args){12 TT t=new TT();13 }14}由于Java虚拟机只加载一次,所以无论类的对象被创建多少次,静态代码块只执行一次
代码块执行的先后顺序:
静态代码块>构造代码块>构造方法内部代码
xxxxxxxxxx221public class TextOnew{2 public static void main(String[] args) {3 Text t=new Text();4 Text t1=new Text();5
6 }7}8
9class Text{10 public Text(){11
12 System.out.println("构造方法代码块");13
14 }15 {16 System.out.println("构造代码块");17 }18 static {19 System.out.println("静态代码块");20 }21
22}
内部类
在Java中,类中可以定义成员变量和成员方法外,也可以定义类,这样的类称作内部类,内部类所在的类称为外部类。
内部类分类:
成员内部类
静态内部类
方法内部类
匿名内部类
内部类和外部类经过Java编译器编译后生成的两个类是独立的
内部类是外部类的一个成员,因此能访问外部类的任何成员(包括私有成员),但外部类不能直接访问内部类的成员
内部类可以为静态,可以使用protected和private修饰,外部类只能由public和默认的访问权限
成员内部类
成员内部类是指类作为外部类的一个成员,能直接访问外部类的所有成员,但外部类访问内部的成员需要外部类创建内部类的对象,使用内部类的对象来访问内部类中的成员。
同时外部类访问内部类需要通过外部类去创建内部类对象。
创建内部类对象的语法:
外部类名.内部类名 变量名=new 外部类名().new 内部类名();
xxxxxxxxxx151public class TextOnew{2 public static void main(String[] args) {3 //实例化内部类对象4 Text.tt ttt=new Text().new tt();5 }6}7class Text{8 private String name="LIBAI";9 class tt{10 public tt(){11 System.out.println(name);//直接访问外部类成员变量name12 }13 }14}15
注意:
成员内部类不能定义静态变量、静态方法和静态内部类,这是因为当外部类被加载时,内部类是非禁止的,那么Java在编译时就不会初始化内部了中的静态成员
静态内部类
使用static修饰内部类称为静态内部类
静态内部类可以有实例成员和静态成员,它可以直接访问外部类的静态成员,但如果想要访问外部类的实例成员就必须通过外部类的对象去访问。
如果在外部类外访问静态内部类成员则不需要创建外部类对象,只需要创建内部类对象即可。
创建内部类对象的格式:
外部类名.内部类名 变量名 = new 外部类名.内部类名()
xxxxxxxxxx181
2class Text{3 //外部类的私有静态成员4 private static String name="LIBAI";5 //外部类的实例成员6 private String adrss="BeiJin";7 8 //创建静态内部类9 static class inner{10 11 public inner(){12 private static String name="MaoZheDong";13 //访问外部类的静态成员14 System.out.println(Text.name);15 16 }17 }18}静态内部类中,要想访问外部类的静态成员通过“外部类名.静态成员”方式访问,若是要访问静态内部类的静态成员,通过“外部类名.内部类名.静态成员”的方式,不需要创建外部类和静态内部类的对象。若是想要访问静态内部类的实例成员,需要通过创建内部类对象——即外部类名.内部类名 变量名 = new 外部类名.内部类名()
方法内部类
方法内部类是指在成员方法中定义的类,它于局部变量相似,作用域为定义它的代码块,因此它只能在定义该内部类的方法内部实例化,不可以在此方法外对其实例化
xxxxxxxxxx241
2public class one {3
4 public static void main(String[] args) {5
6 tt t=new tt();//实例化外部类7
8 }9
10}11class tt{12 //定义一个构造方法13 public tt(){14// 定义一个方法内部类15 class inner{16// 构造方法——实例化时自动调用17 public inner(){18 System.out.println(11+22);19 }20 }21 inner in =new inner();//在定义的放内实例化22 }23}24
匿名内部类
匿名内部类就是没有名称的内部类。创建匿名内部类时会立即创建一个该类的对象,该类定义立即消失,匿名内部类不能重复使用。
xxxxxxxxxx181
2public class noNameInnerClass {3 public static void main(String[] args) {4//创建匿名内部类5 Text t=new Text(){6 public void say(){7 System.out.println(22+33);8 }9 };10 t.say();11 }12}13class Text{14 public void say(){15 System.out.println(11+33);16 }17}18
类的继承
继承的概念:
在面向对象的程序设计中,继承现实代码重用,即在已有的类的基础上定义新的类,新的类继承已有类的行为和属性,并扩展新的功能,而不需要把已有的类的内容再编写一遍。
已有的类被称为父类或基类,新的类被称为子类或派生类。
子类继承父类的语法格式:
class 子类名 extends 父类名{
属性和方法
}
Java使用extends关键字指明两个类之间的继承关系。子类继承父类的属性和方法,也可以添加新的属性和方法。
xxxxxxxxxx191
2public class Extends {3 public static void main(String[] args) {4 son s=new son();5 //My name is李白6 }7}8//定义父类9class Parent{10 String Frist_name="李";11}12//定义子类13class son extends Parent{14 String name="白";15 public son(){16 System.out.println("My name is"+Frist_name+name);17 }18}19
重写父类方法
在继承关系中,子类继承了父类的方法,如果要求在子类中使用父类的方法输出不一样的内容,这时就需要子类修改父类的方法,即子类重新定义从父类中继承的成员方法,这个过程就叫做方法重写或则重载。子类重写的方法不能拥有比父类更加严格的访问权限
xxxxxxxxxx111class Parent{2 public void say(){3 System.out.println("Hi gril");4 }5}6class son extends Parent{7 //子类重写父类的方法8 public void say(){9 System.out.println("Hi boy");10 }11}方法的重载和方法重写的区别:
方法的重载是在同一个类中,方法的重写是在子类语父类中。
方法重载要求:方法名相同,参数个数或者参数类型不同。
方法重写要求:子类与父类的方法名相同、返回值类型和参数列表相同。
super关键字
当子类重写父类方法后,子类对象将无法访问父类被重写的方法,如果需要在子类中访问父类的被重写的方法,使用super关键字来实现
xxxxxxxxxx121
2class Parent{3 public void say(){4 System.out.println("Hi gril");5 }6}7class son extends Parent{8 public void say(){9 super.say();//这样即会执行子类的say()方法也会执行父类的say()方法10 System.out.println("Hi gril");11 }12}final关键字
在Java中为了考虑安全因素,要求某些类不允许被继承或者不允许被子类修改,这时可以用final修饰。final可用于修饰类、方法和变量
final修饰的类不能被继承
final修饰的方法不能被之类重写
final修饰的变量是常量,初始化后不能被更改
final修饰类
使用final修饰的类被称为最终类,表示不能再被其他类继承
xxxxxxxxxx91
2final class Parent(){3 public Parent(){4 System.out.println("say hello");5 }6}7class son extends Parent{8 9}这样写的代码会报错,表示son类不能继承Parent类
final修饰方法
使用final修饰的方法称为最终的方法,表示子类不能重写此方法
xxxxxxxxxx111
2class Parent{3 public final void say(){4 System.out.println("hello Parent");5 }6}7class son extends Parent{8 public void say(){9 System.out.println("hello Son");10 }11}会直接报错
final修饰变量
final关键字修饰的变量称之为常量,只能被赋值一次,如果再对该变量进行赋值会报错
final修饰局部变量
xxxxxxxxxx61public class TEST{2 public static void main(String[] args){3 final int a=1;4 a=2;5 }6}final修饰成员变量
xxxxxxxxxx121class Parent{2 final int a;3 public Parent(){4
5 }6}7public class TEST{8 public static void main(String[] args){9 Parent p=new Parent();10 System.out.println(p.a);//会报错11 }12}java虚拟机不会为final修饰的变量进行初始化
抽象类和接口
抽象类
java中可以定义不包含方法体的方法,方法的方法体由该类的子类根据实际需求实现,这样的方法称为抽象方法,包含抽象方法的类必须是抽象类。
使用关键字abstract定义抽象方法,只有方法的声明,没有方法的方法体。
使用abstract修饰的类称为抽象类,抽象类可以不包含任何抽象方法
xxxxxxxxxx91
2//用abstract修饰抽象类3
4abstract class Parent{5 6 //abstract修饰抽象方法,只能声明,没有实现7 8 public abstract void say();9}需要注意的是:
使用抽象类时,抽象类不能被实例化,即不能使用new关键字来创建对象,因为抽象类中可以包含抽象方法,抽象放啊只能被声明,没有方法体,不能被调用,因此,必须通过子类继承抽象类方法去实现抽象方法
xxxxxxxxxx181
2abstract class Parent{3 public abstract void say();4}5//子类继承父类6class Son extends Parent{7 //子类使用分类的抽象方法8 public void say(){9 System.out.println("hi hi hi");10 }11}12//---------------------------------------------------------------//13public class Test{14 public static void main(String[] args){15 Son son = new Son();16 son.say();17 }18}需要注意的是:具体子类必须实现父类的所有抽象方法,否则子类必须声明为抽象类,即,抽象的父类里面有几个抽象方法,普通的子类继承父类时必须要全部使用父类声明好的抽象方法,如果子类只想使用某一个父类的抽象方法,则该子类需要自定义为抽象的类,即抽象类继承抽象类。
xxxxxxxxxx121
2abstract class Parent{3 //定义父类两个抽象方法4public abstract void say();5 public abstract void sing();6}7class son extends Parent{8 //仅使用一个父类里继承过来的抽象方法9 public void say(){10 System.out.println("hello world!");11 }12}像上面的例子,子类只是使用了一个父类里面的抽象方法,当运行程序时会报错!所以必须使用父类里全部的抽象类。
抽象方法不能使用static关键字来修饰,因为static修饰的方法可以通过类名来调用
抽象方法也不能使用final关键字修饰,因为final修饰的方法不能被重写
抽象方法也不能被private关键字修饰,因为子类不能访问private修饰的方法和属性
子类对象实例化时会默认调用父类的无参数的构造方法,也可以通过super关键字调用父类中有指定参数的构造方法