java笔记

面向对象
1.1、理解面向对象
面向对象是相对面向过程而言
面向对象和面向过程都是一种思想
面向过程强调的是功能行为
面向对象将功能封装进对象,强调具备了功能的对象
面向对象是基于面向过程的
对象和类的概念:
对象:对象用计算机语言对问题域中事物的描述,对象通过“属性(attribute)”和“方法(method)”来分别对应事物所具有的静态属性和动态属性。
类:类是用于描述同一类形的对象的一个抽象的概念,类中定义了这一类对象所应具有的静态和动态属性。
1.2、面向对象的特点
是一种符合人们思考习惯的思想
可以将复杂的事情简单化
将程序员从执行者转换成了指挥者
完成需求时:先要去找具有所需的功能的对象来用;如果该对象不存在,那么创建一个具有所需功能的对象;这简化开发并提高复用;
1.3、面向对象开发、设计、特征
开发的过程:其实就是不断的创建对象,使用对象,指挥做事情
设计的过程:其实就是在管理和维护对象之间的关系
面向对象的特征:封装(encapsulation)、继承(inheritance)、多态(polymorphism)
2.1、类的定义
生活中描述事物无非就是描述事物的属性和行为
如:人有身高,体重等属性,有说话,打球等行为
Java中用类class来描述事物也是如此
属性:对应类中的成员变量
行为:对应类中的成员函数
定义类其实在定义类中的成员(成员变量和成员函数)
我们的语言:成员变量 = 属性 + 方法 = 函数
2.2、成员变量和局部变量的区别
成员变量
成员变量定义在类中,在整个类中都可以被访问
成员变量随着对象的建立而建立,存在于对象所在的堆内存中
成员变量有默认初始化值
局部变量
局部变量只定义在局部范围内,如:函数内,语句内等
局部变量存在于栈内存中
作用的范围结束,变量空间会自动释放
局部变量没有默认初始化值
class Person{
private String name;                  //定义一个成员变量
public void setName(String name){     //定义一个设置成员变量的方法
this.name = name;                 //this表示指向当前实例
}
public String getName(){              //定义一个获取成员变量的方法
return name;
}
}
public class PersonDemo{
public static void main(String[] args){
Person per = new Person();        //实例化一个对象
per.setName("王五");              //对对象的属性进行修改
System.out.println(per.getName());//使用对象的功能
}
}
2.3、匿名对象
匿名对象是对象的简化形式
匿名对象两种使用情况
1、当对对象方法仅进行一次调用的时
2、匿名对象可以作为实际参数进行传递
3、封装(encapsulation):是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:将变化隔离、便于使用、提高重用性、提高安全性
封装原则:将不需要对外提供的内容都隐藏起来、把属性都隐藏,提供公共方法对其访问
4.1、private(私有)关键字
private是一个权限修饰符、用于修饰成员、被私有化的成员只在本类中有效
常用于将成员变量化,对外提供对应的set,get方法对其进行访问,提高对数据访问的安全性
4.2、构造函数
特点:函数名与类名相同、不用定义值类型、不可以写return语句
作用:给对象进行初始化
注意:默认构造函数是一个无参的构造函数,若没有创建构造函数,系统会就默认创建一个无参的构造函数,若创建了构造函数不论有参无参,系统都不会再创建,特别注意在创建了有参构造函数时最好再创建一个无参构造函数,因为用户在实例化对象时不清楚是否有参无参
 多个构造函数是以重载的形式存在的
class method(){
private int age;
public method(){         //创建一个无参构造函数,也就是系统会创建的默认构造函数
System.out.println("这是一个无参构造函数!");
}
public method(int age){ //创建一个有参构造函数,还可以创建多个创建的有参函数
System.out.println("这是一个有参构造函数!");
}
}
5、this关键字
特点:this代表其所在函数所属对象的引用,也就是说"this"代本类对象的引用
什么时候使用?
当在函数内需要用到调用该函数的对象时,就用"this";this可以表示当前对象,this可以访问构造方法(注意:this调用只能放在构造方法的第一行)
6、String
String实例化的两种方式
String name1 = "haoren";
String name2 = new String("huairen");
两种实例化的区别
第一种
String name1 = "haoren";
String name2 = "haoren";
name1和name2指向了同一空间,“haoren”只存储了一次
第二种
String name4 = new String("haoren");
String name5 = new String("haoren");
name4和name5开辟了不同的空间
String内容的比较(equals)
String name = "haoren";
//if("haoren".equals(name)){
if(name.equals("haoren")){//(注意不能这样写,如果name=null)就会报空指针异常
System.out.println("ok");
}
//函数:charAt()
//String name = "我是好人,你是坏人!!!";
//System.out.println(name.charAt(2));
matches()   //正则表达式
if("[email protected]".matches("\\w+@\\w+[.]\\w+")){
System.out.println("合法!!!");
}else{
System.out.println("不合法!!!");
}
split()    //分割
String[] a = "我是:好人".split(":");
System.out.println(a[0]);
startsWith(String prefix)  //判断开头
String name ="我是好人";
System.out.println(name.startsWith("我"));
endsWith(String suffix) 
String name ="我是好人";//判断结尾
System.out.println(name.endsWith("人"));
trim()     //清除开头与结尾的空格,没有中间
String name ="   我是好人   ";
System.out.println(name+"!!!");
System.out.println(name.trim()+"!!!");
replace()  //替换
System.out.println(name.replace("好人","坏人"));
7、static(静态)关键字
用于修饰成员(成员变量和成员函数),修饰成员变量时,可以实现数据共享
被修饰后的成员具备的特点:随着类的加载而加载、优先于对象存在、被所有对象所共享、可以直接被类名调用
注意:静态方法只能访问静态成员、静态方法中不可以定this,super关键字、主函数是静态的
static的特点:1、static是一个修饰符,用于修饰成员。
 2、static修饰的成员被所有的对象所共享。
 3、static优先于对象存在,因为static的成员随着类的加载就已经存在了。 
     4、static修饰的成员多了一种调用方式,就可以直接被类名所调用 。 类名.静态成员 。
     5、static修饰的数据是共享数据,对象中的存储的是特有数据。
成员变量和静态变量的区别:
1、两个变量的生命周期不同。
成员变量随着对象的创建而存在,随着对象的被回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同。
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同。
成员变量也称为实例变量。
静态变量称为类变量。 
4、数据存储位置不同。
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据.
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据.
8、代码块:执行顺序与位置没有影响
普通代码块
比构造函数先执行,且会多次调用
class method{
{
System.out.println("普通代码块!");    //第一步调用
}
public method(){
System.out.println("构造函数!");      //第二步调用
}
}
静态代码块
比普通代码块更快,且只执行一次
class method{
{
System.out.println("普通代码块!");    //第二步调用 
}
static{
System.out.println("static代码块!");  //第一步调用
}
public method(){
System.out.println("构造函数!");      //第三步调用
}
}
9、单例设计模式:只创建一个实例
饿汉式:一加载就创建实例,缺点:有可能造成内在浪费,比如一次都用不到这个实例
懒汉式:需要实例时才创建,弥补饿汉式的缺点
public class test{
public static void main(String[] args){
method me1 = method.getMethod();
method me2 = method.getMethod();
me1.speak();
me2.speak();
}
}
class method{   //饿汉式
static method m = new method();
private method(){
}
public void speak(){
System.out.println("haoren");
}
public static getMethod(){
return m;
}
}
class method{  //懒汉式
static method m;
private method(){
}
public void speak(){
System.out.println("haoren");
}
public static getMethod(){
if (m == null)
s = new method();
return s
}
}
10.1、继承的概述
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单独的那个类即可
多个类可以称为子类,单独这个类称为父类或者超类
子类可以直接访问父类中的非私有的属性和行为
通过"extends"关键字让类与类之间产生继承关系
继承的出现提高了代码的复用性
继承的出现让类与类之间产生了关系,提供了多态的前提
注意:要访问父类的私有属性必须用共有的"set"和"get"方法;子类不能降低父类继承过来的方法的权限
10.2、继承的特点
Java只支持单继承,不支持多继承
一个类只能有一个父类,不可以有多个父类
例:class SubDemo extends Demo{}         //正确
class SubDemo extends Demo1,Demo2……  //错误
Java支持多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}
定义继承需要注意:
不要仅为了获取其他类中某个功能而去继承
类与类之间要有所属("is a")关系,xx1是xx2的一种
10.3、super关键字
super和this的用法相同
this代表本类应用
super代表父类引用
当子父类出现同名成员时,可以用super进行区分
子类要调用父类构造函数时,可以使用super语句。(必须放在第一行)
10.4、函数覆盖(Override)
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写
父类中的私有方法不可以被覆盖
在子类覆盖方法中,继承使用被覆盖的方法可以通过super函数名获取
覆盖注意事项:
覆盖时,子类方法权限一定要大于等于父类方法权限(从private到default不算是覆写)
子类与父类同名属性也会出现覆盖
静态只能覆盖静态
覆盖的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
class Father{
public void method(){
System.out.println("我是父类方法!");
}
}
class Son extends Father{
public void method(){
System.out.println("我覆盖了父类方法!");
}
}
public class test{
public static void main(String[] args){
Son son = new Son();
son.method();        
}
}
10.5、子类的实例化过程
子类中所有的构造函数默认都会访问父类中空参数的构造函数
因为每一个构造函数的第一行都有一条默认的语句super()
子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的
当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数
10.6、final关键字
final可以修饰类,方法,变量
final修饰的类不可以被继承
final修饰的方法不可以被覆盖
final修饰的变量是一个常量,只能赋值一次
内部类只能访问被final修饰的局部变量
public class method{
public static void main(String[] args){

}
}
final class method1{
public final void test(){
}
}
class method2 extends method1{  //错误:无法从最终method1进行继承
public void test(){   //错误: method2中的test()无法覆盖method1中的test()
int k = 5;
}
}
11.1、抽象类(abstract)
抽象定义
抽象就是从多个事物中将共性的,本质的内容抽取出来
例:狼和狗共性都是犬科,犬科就是抽象出来的概念
抽象类
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类
抽象方法的由来
多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法
例:狼和狗都有吼叫的方法,可是吼叫内容不一样的,所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节
11.2、抽象类的特点
抽象类和抽象方法必须用abstract关键来修饰
抽象方法只有方法声明,没有方法体,定义在抽象类中
格式:修饰符 abstract 返回值类型 函数名(参数列表);
抽象类不可以被实例化,也就是不可以用new创建对象,原因如:
抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗
而且抽象类即使创建了对象,调用抽象方法也没有意义
抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类
11.3、抽象类问题
抽象类中是否有构造函数?
有,抽象类不能实例化,但是有构造方法,因为子类在继承时会自动调用父类构造方法
抽象类可不可以有非抽象方法?
可以,却很少用
12.1、接口(interface)
接口就是标准,接口没有变量;有也要用"final"改成常量;接口常量与方法可以简写,不要修饰词;接口可以多实现,多继承,多层继承
interfaca USB1{
//public final double width = 4.5;
double width = 4.5;             //可以简写,与上面结果一样
viod getConnection1(){
}
}
interfaca USB2{                     //可以多层继承,用"extends",下面就只需要连接这一个接口,与下面结果一样
viod getConnection2(){
}
}
class up implements USB1,USB2{
public void getConnection1(){
System.out.println("连接实现");
}
public void getConnection2(){
System.out.println("连接更快");
}
}
注意:如果遇到既可以创建成抽象类,又可以创建成接口时,尽量创建成接口,为以后的继承留余地
适配器设计模式:当一个接口的方法太多,而又只需要实现其一两个方法时,可以创建一个中间抽象类
public class test{
public static void main(String[] args){
childent child = new childent();
child.test2();
}
}
interface AAA{             //创建一个多个方法的接口
void test1();
void test2();
void test3();
}
abstract class AA implements AAA{  //创建一个抽象类,连接接口,并实现接口的所有方法
public void test1(){}
public void test2(){}
public void test3(){}   //这些方法不是抽象方法
}
class childent extends AA{  //继承抽象父类
public void test2(){
System.out.println("test2的方法!!!");  //继承抽象父类的方法
}
}
13.1、多态:某一类事物的多种存在形态
体现:父类或者接口的引用指向或者接收自己的子类对象,父类可以接收子类对象实例
作用:多态的存在提高了程序的扩展性和后期可维护性
前提:需要存在继承或者实现关系;要有覆盖操作
特点:成员函数:编译时要查看引用变量所属的类中是否有所调用的成员;运行时要查看对象所属的类中是否有所调用的成员
     成员变量:只看引用变量所属的类
  public class test{
public static void main(String[] args){
Fruit b = new Banana();    //用父类接收子类对象实例
Fruit a = new Apple();  
b.test1();         //调用父类方法时实际调用的是被子类覆盖的方法
a.test1();
b.test2();       //如果子类没覆盖,就调用父类的方法
}
  }
  class Fruit{
public void test1(){
System.out.println("什么味道?");
}
public void test2(){
System.out.println("你猜什么味道!");
}
  }
  class Banana extends Fruit{
public void test1(){
System.out.println("滑的");
}
  }
  class Apple extends Fruit{
public void test1{
System.out.println("脆的");
}
  }
13.2、转型
向上转型:也就是父类接收子类的对象实例
Fruit b = new Banana();
向下转型(强制转换):向下转型必须先向上转型,在向下转型时可以先用"instanceof"判断一下所属类
Fruit b = new Banana();
Banana f = (Banana)b;  //先向上转型,才可向下强制转换
if (b instanceof Banana){
System.out.println("类型符合,可以转!");
Banana f = (Banana)b;
}
else{
System.out.println("类型不符合,不可以转");
}
13.3、工厂设计模式(不完整):
public void class Test{
public static void main(String[] args){
Person p = new Person();                //创建一个用户对象
Drink d = ProductionDrink("咖啡");//创建一个饮料引用,指向其下的一个子类
    //Coffee d = (Coffee)ProductionDrink("咖啡");  //这种方式与上面效果一样,但是ProductionDrink返回的是Drink类型,这是向下转型,因此要强制转换
p.drink(d);           //调用人的方法


}
}
class Person{                                             //创建一个人
public void drink(Drink d){               //具备选择饮料的功能
d.getDrink();                             
}
}
class DrinkFactory{                                  //创建饮料工厂
public static Drink productionDrink(String name){  //生产饮料的方法,传入用户需要的饮料,返回饮料类型,设置成静态方法可以直接用类名调用(工具类)
if (name.equals("可乐")){                                  //判断饮料,真就创建一个对象实例,其实此处就等于向上转型
return new Coke();
}
if (name.equals("橙汁")){
return new Orange();
}
if (name.equals("咖啡")){
return new Coffee();
}
return null;                                              //没有匹配就返回空
}
}
interface Drink{                                 //创建一个饮料接口
void getDrink();                        //创建一个获取饮料的方法
}
class Coke implements Drink{          //创建一个可乐并实现饮料接口
public void getDrink(){             //覆盖接口方法
System.out.println("我喝可乐");
}
}
class Orange implements Drink{
public void getDrink(){
System.out.println("我喝橙汁");
}
}
class Coffee implements Drink{
public void getDrink(){
System.out.println("我喝咖啡");
}
}
13.4、代理设计模式:将核心代码与普通代码分开,提高代码的安全性,更方便维护
public void Test{
public static void main(String[] args){
new ProxyNet().connection();   //创建代理对象并实现方法
}
}
interface Net{                 //创建一个网络接口
void connection();
}
class Connect implements Net{  //创建连接并实现接口
public void connection(){
System.out.println("连接成功");
}
}
class ProxyNet implements Net{  //创建一个代理并实现接口
public boolean validate(String user,String pass){  //验证帐号密码
boolean b = false;
if ((user.equals("haoren"))&&(pass.equals("123456"))){
b = true;
return b;
}
else{
System.out.println("密码错误");
return b;
}
}
public void connection(){          //覆盖接口方法
if (validate("haoren","123456")){
new Connect().connection();  //创建连接对象,并调用方法
}
}
}
13.5、内部类:将一个类定义在另一个类里,特点:可以直接访问外部类的私有变量
public void class Test{
public static void main(String[] args){
Person p1 = new Person("胖子");   //实例人类对象,并赋值
p1.getInner().jump();                      //调用方法来实例内部类对象,并调用其方法
Person p2 = new Person("小子");   //实例人类对象,并赋值
Person.Inner pi = p2.new Inner();  //用外部类来实例化内部类,与上面相比,省略了调用方法,使内部类更安全
pi.jump();                    
}
}
/**
*创建一个人类
*/
class Person{
/**
*私有变量
*/
private String name;
/**
*无参构造函数
*/
public Person(){
}
/**
*有参构造函数,为变量赋值
*/
public Person(String name){
this.name = name;
}
/**
*创建一个内部类
*/
class Inner{
/**
*创建一个跳的方法,并调用外部类私有变量
*/
public void jump(){
System.out.println(name+"的心脏在跳");
}
}
/**
*创建一个返回内部类对象的方法
*/
public Inner getInner(){
return new Inner();
}
}
13.6、静态内部类:可以直接外部类加内部类来实例;语法:new 外部类.内部类();
public void class Test{
public static void main(String[] args){
new Person.Inner().jump("胖子");     //实例化一个内部类对象时,用内部方法传参为私有变量赋值                    
}
}
/**
*创建一个人类
*/
class Person{
/**
*私有变量
*/
private static String name;
/**
*无参构造函数
*/
public Person(){
}
/**
*有参构造函数,为变量赋值
*/
public Person(String name){
this.name = name;
}
/**
*创建一个内部类
*/
static class Inner{
/**
*创建一个跳的方法,并实例一个外部类,调用外部类私有变量
*/
public void jump(String s){
new Person(s);
System.out.println(name+"的心脏在跳");
}
}
}
13.7、方法内部类:将内部类写在外部类的方法体里;内部类在接收外部类函数形参时,形参必须被final修饰,JDK1.8可以不写final,但是为了兼容,最好写上
public class test{
public static void main(String[] args){
Person p = new Person();  //实例一个人类的对象
p.t("sdfsdf");  //调用方法就可以访问内部类
}
}
class Person{    //创建一个人类
  public void t(final String s){   //形参要final修饰
class inner{    //创建内部类
public void jun(){
System.out.println(s);  //接收形参
}
}
new inner().jun();   //在方法内实例内部类
}
}
13.8、匿名内部类:将定义,实例化,使用三位一体化,更灵活
public class Test{
public static void main(String[] args){
Method m = new Method();    //实例类的对象
m.method(new AA(){               //在调用该类方法时,要为此方法创建一个临时的接口子类,也就是匿名内部类,它的名字都是系统自动生成,生命周期只在这个语句内
public void test(){
System.out.println();
}});
new AA(){                               //创建一个匿名类
public void test(){          //重写接口方法
System.out.println("匿名内部类");
}}.test();                                  //调用方法
}
}
/**
*创建一个接口,声名一个方法
*/
interface AA{
void test();
}
/**
*创建一个类,方法调用接口AA的子类对象
*/
class Method{
public void method(AA a){
System.out.println(a);    //输出对象名
}
}
注意:接口里边可以定义内部接口和抽象类;抽象类里也可以定义接口和抽象类
14、装箱和拆箱:jdk1.5之后可以自动装箱和拆箱
基本数据类型的包装类除了"int"是"Integer"和"char"是"Character"外,其它类型都是首字母大写
class method{
int x = 30;
Integer i = new Integer(x);     //装箱:将基本数据类型变为包装类
int temp = i.intValue();          //拆箱:将包装类变为基本数据类型
Integer i = 30;                      //自动装箱成Integer
Float j = 30.3f;                     //自动装箱成Float
int x = i;                               //自动拆箱成int
float y = j;                            //自动拆箱成float
String str = "30";                 //由数字组成的字符串
int x = Integer.parseInt(str);//将字符串变为int型
}
15.1、异常:异常就是导致程序终止的一种指令流,异常会使程序终止执行
异常的体系:Throwable
Error:通常出现重大问题如:运行的类不存在或者内在溢出等;不编写针代码对其处理
Exception:在运行时运行出现的一起情况,可以通过try catch finally
Exception和Error的子类名都是以父类名作为后缀
15.2、Throwable中的方法
getMessage():获取异常信息,返回字符串
toString():获取异常类名和异常信息,返回字符串
printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void
15.3、throws和throw
throws用于标识函数暴露出的异常
throw用于抛出异常对象
thorws用在函数上,后面跟异常类名
throw用在函数内,后面跟异常对象
15.4、异常处理
try{
需要检测的代码;
}
catch(异常类 变量){
异常处理代码;
}
finally{
一定会执行的代码;
}
finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0);
15.5、自定义异常:继承Exception或者其子类;通过构造函数定义异常信息
例:class DemeException extends Exception{
DemeException(String message){
super(message);
}
}
通过throw将自定义异常抛出
注意:1、RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明
 2、一个方法被覆盖时,覆盖它的方法必须抛出相同的异常的子类
 3、如果父类抛出多个异常,那么覆定(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常
16.1、包(package)
对类文件进行分类管理
给类提供多层命名空间
写在程序文件的第一行
类名的全称是:包名.类名
包也是一种封装形式
编译:javac -d . PackageDemo.java ("-d":表示创建目录;".":表示在当前目录创建,也可以在其他目录创建)
运行:java 包名.类名
16.2、包之间的访问
被访问的包中的类权限必须是public的
类中的成员权限:public或者protected
protected是为其他包中的子类提供的一种权限
16.3、四种权限:
public:同一类中(可以)、同一包中(可以)、不同包子类(可以)、不同包中(可以)
protected:同一类中(可以)、同一包中(可以)、不同包子类(可以)、不同包中(不可以)
default:同一类中(可以)、同一包中(可以)、不同包子类(不可以)、不同包中(不可以)
private:同一类中(可以)、同一包中(不可以)、不同包子类(不可以)、不同包中(不可以)
16.4、import
简化类名
一个程序文件中只有一个package,可以有多个import
用来导包中的类,不导入包中的包
通常写"import mypack.Demo;",而不写"import mypack.*;"是为了代码可读性

你可能感兴趣的:(Class,多态,inheritance)