---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ---------------------
构造函数与this的使用,构造函数是为了使对象更好的进行初始化,当没有写入构造函数时,系统自带有,如果有写入,则系统不再默认
每次创建对象,对应的构造函数就会只执行一次。
this的两个作用:1.用来指示调用对象 2.用于构造函数内部调用 3.用于对象自己与其他对象之间的相同内容的操作
----------------------------------------------------------------------------------------------------------------------
静态:Static 关键字
用法:是一个修饰符,用来修饰成员(成员变量,成员函数)
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用 类名.静态成员
static 特点:
1.随着类的加载而加载,随着类的消失而消失,寿命最常
2.优先于对象存在,在方法区内
3.被所有对象所共有,在内存中的方法区
4.可以直接可以用类名调用
实例变量和类变量的区别:
1.存放位置
类变量随着类的加载而存在于方法区中
实例变量随着对象的建立而存在于堆内存中
2.生命周期
类变量随着类的加载而加载,随着类的消失而消失,寿命最常
实例变量随着对象的存在而存在,消失而消失
注意:1.静态方法只能访问静态成员;非静态方法即可以访问静态也可以访问非静态象存在
2.静态方法中不可以定义thissuper 关键字,应为静态优先于对象存在
静态有利有弊
利处:对象共享空间,节省空间,直接用类名调用
弊处:生命周期长,访问出现局限性(静态只能访问静态)
----------------------------------------------------------------------------------------------------------------------
public static void main(String[] args)
主函数:是一个特殊的函数,作为程序的入口,可以被jvm(虚拟机)调用
主函数的定义:
public:代表着该函数访问权限是最大的
static:代表主函数随着类的加载已经存在了
void:主函数没有具体的返回值
main:不是关键字,但是一个特殊的单词,可以被JVM识别
(String[] args):函数的参数,参数类型是一个数组,该数组中的元素是字符串,即字符串数组
主函数是固定格式的:jvm识别
jvm 在调用主函数时,传入的是new String[0],说明我们也可以向里面传值。java MainDemo haa hh hhi
----------------------------------------------------------------------------------------------------------------------
静态代码块
格式:
static
{
静态代码块中的执行语句;
}
特点:可以多个,随着类的加载而执行,只执行一次,所以是【最先执行的】,
优先于主函数
用途:用于给类进行初始化的。
【需求:】验证静态代码块(给类初始化)》构造代码块(给对象【人出生都裸体】初始化)》构造函数(对应对象初始化【有些人出生可能穿衣服】)的执行顺序
----------------------------------------------------------------------------------------------------------------------
对象初始化
Person p = new Person("lll",20)
该句话都做了什么事情?
1.因为new用到了Person.class,所以会找到Person.class文家并加载到内存中
2.执行该类中的static代码块。如果有的话,给Person.class类进行初始化。
3.在堆内存中开辟空间,分配内存地址。
4.在堆内存中建立对象的特有属性,并进行默认初始化。如:String 为 null,int 为 0.
5.对属性进行显示初始化。
6.对对象进行构造代码块初始化。
7.对对象进行对应的构造函数初始化。
8.将内存地址给栈内存中的P变量
----------------------------------------------------------------------------------------------------------------------
设计模式:解决某一类问题最行之有效的方法。
java中23中设计模式
单例设计模式:解决一个类中只能够穿件一个对象。
想要保证对象唯一
1.为了避免其他程序过多建立该类对象,那么先禁止其他程序建立对象
2.为了让其他程序访问到该类对象,在自己的类中建立对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三部分怎么用代码体现呢?
1.将构造函数私有化
2.在类中创建一个本类对象
3.提供一个方法可以获取到该对象。
对于事物该怎么描述,就怎么描述
当需要该事物的对象保证在内存中唯一性时,用以上三步就可。
先初始化对象
称为:饿汉式
class Single
{
private Single(){}
private Single s = new Single();
public static Single getInstance(){
return s;
}
}
对象是方法被调用时,才初始化,也叫做对象延时加载
称为:懒汉式
类一加载Single s=NULL。当要调用时才创建对象。
class Single
{
private Single(){}
private Single s = null;
public static Single getInstance(){
if(s == null){
synchronized(Single.class){
if(s == null){
s = new Single()
return s;
}}}}
}
----------------------------------------------------------------------------------------------------------------------
要求:获取一段程序运行的时间
原理:获取程序开始和结束的时间并相减即可
当代码完成优化后,就解决了这类问题
这种方式:模板方法设计模式
什么是模板方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,
而确定的部分在使用不确定的部分,那么这时我们就把不确定的部分暴露出去,
由该类的子类来完成。
abstract class GetTime//用于某一段代码运行时间的类。{
public final void getTime()//final 是子类不能复写该方法{
long start = System.currentTimeMillis();//获取当前毫秒值
runCode();
long end = System.currentTimeMillis();
System.out.print("毫秒:"+(end - start));
}
public abstract void runCode();//【不确定部分暴露】抽象类中抽象类留给子类复写
}
class SubTime extends GetTime{
public void runCode(){
for(int x=0;x<1000;x++){
System.out.println(x);
}
}
}
class MoBanDemo{
public static void main(String[] args){
SubTime sub = new SubTime();
sub.getTime();
}
}
----------------------------------------------------------------------------------------------------------------------
接口:初期理解,可以认为是一个特殊的抽象类
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
class用来定义类
interface 用于定义接口
接口定义时,格式特点:
1.接口常见定义:常量,抽象方法
2.接口中的成员都有固定修饰符。
常量:public static final
方法:publicabstract
记住:接口中的成员都是public的。
接口:是不可以创建对象的,因为有抽象方法。
需要被子类实现,子类对接口中的抽象方法全部都覆盖后,子类才可以实例化。
如果子类中没有方法为空,则子类继承了接口的方法,子类也就是一个抽象类了
1.接口可以被类多实现,也是对多继承不支持的转换形式,java支持多实现
注意:不能出现子类多实现时,接口中出现同名不同类型【可出现同名同类型】的函数(如下示意),这会导致子类对象调用show方法时,不知道调用那个show。
2.接口与接口之间是继承关系,接口与接口之间支持多继承
没有方法体,不会导致调用父类的函数时,如果多个父类中出现同名同类型不同主体的函数,就会导致子类对象不知道调用哪一个的情况
当然在多实现中,多个接口中可以出现同名同类型的函数,但是不能出现同名不同类型的函数,原因跟上所述一样
接口的特点:
1.接口是对外暴露的规则
2.接口是程序的功能扩展
3.接口可以用来实现
4.类与接口之间是实现关系,而且类可以继承一个类与接口之间可以有继承关系
5.接口与接口之间可以有继承关系
接口的出现提高了功能的扩展性,接口型引用指向自己的子类对象,也提高了程序
扩展性(多态),接口降低了功能的耦合性,提高了功能的扩展性,提供了规则
继承是你属于我,接口是你像我中的一个;是体系之外的功能扩展。
----------------------------------------------------------------------------------------------------------------------
多态:某一类事物的多种存在的形态
*例如:动物中猫、狗
*猫这个对象对应的类型是猫类型
猫 x = new 猫();
*同时猫也是动物中的一种,也可以把猫称为动物
动物 y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型
父类型引用指向了子类对象。
【转型】
1.多态的体现
父类的引用指向了自己的子类对象;
父类的引用也可以接收自己的子类对象。【不能调用父类中没有,而子类中有的函数】
2.多态的前提
必须是类与类之间有关系,要么是继承,要么是实现;通常还有一个前提,就是存在覆盖。
3.多态的好处
多态的出现大大提高了程序的扩展性。
4.多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类的成员。
5.多态的应用
6.多态的出现代码中的特点(多态使用的注意事项)
子类覆盖父类方法,子类方法权限要不小于父类方法权限
主函数调用这所在类中的方法,只能调用静态方法,主函数是静态的,静态只能调用静态
Animals a = new Cat();//父类应用指向子类对象//【类型提升,向上转型】猫-》动物
a.eat();//父类引用指向子类对象,并调用父类和子类共有函数
//如果要调用猫的特有方法,如何操作?
//强制将父类的引用,转成子类类型【向下转型】【不能将父类对象强转型为子类类型】
Cat c = (Cat)a;
//我们能转换的是父类应用指向了自己的子类对象时,该引用可以被提升,也可以
//被强制向下转型。
//多态自始至终都是子类在做着变化。
c.catchMouse();
///a.catchMouse();//父类引用指向子类,不能调用父类中没有,而子类中有的函数
多态中成员的特点:
在多态中非静态成员函数的特点:【因为非静态函数有重写特性】
在编译时期:参阅引用【类型变量所属的类】中是否有调用的方法,如果有,编译通过;如果没有编译失败。
在运行时:参阅【对象所属类】中是否有调用方法。
简单总结:非静态成员函数在多态时,编译看左边,运行看右边。
在多态中成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属类)
在多态中静态成员函数的特点:
无论编译和运行,都看考左边。
----------------------------------------------------------------------------------------------------------------------
Object:是所有对象的直接或者间接父类,传说中的上帝。
该类中定义的肯定是所有对象中功能
Object类中的方法:
1.equals()
所有对象都具有可比较性,是不是同一个
public boolean equals(Object d)
//通过复写Object类中equals(),而public boolean equals(Demo d)是重载了,当然也是可以的,不过多写了方法。
任何对象都可以比较是否相同,其实就是比较是否具有相同的地址值。
2.toString()
把。。变成字符串
----------------------------------------------------------------------------------------------------------------------
内部类
内部类的方位规则:
1.内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有
一个外部类的引用:格式: 外部类名.this
2.外部类要访问内部类,必须创建内部类对象。
访问格式:
1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中
可以直接建立内部类对象。
格式:
外部类名.内部类名变量名 = 外部类对象.内部类对象
Outer.Inner in = new Outer( ).new Inner( );
2.当内部类在成员位置上,就可以被成员修饰符所修饰
比如:private:将内部类在外部类中进行封装
static:内部类就具备了静态的特性。
当内部类被static修饰后,只能直接访问外部类中的Static成员,出现了访问局限
在外部其他类中,如何直接访问静态内部类的非静态方法呢?
new Outer.Inner().function()
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function()
【注意:当内部类中定义了静态成员,该内部类必须是static】
当外部类中的静态方法访问,内部类时,内部类也要是静态的。
内部类的运用范围:
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事物在使用外部事物的内容。例如:人体中的心脏。
【小帖士:static 是成员修饰符,成员修饰符】
内部类定义在局部时:
1.不可以被成员修饰符修饰
2.可以直接访问外部类的成员,因为持有外部类中的引用
但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。
void method(final int a)//内部类定义在局部成员中{
fanil int x = 3;
class Inner{
static void function()
{
System.out.println(x);
}
}
new Inner().function();
}
//Outer out = new Outer();
//out.method(7);
//out.method(8);这样是可以的,因为a是局部变量,语句执行完,在栈中a消失。
------------------------------------------------------
【匿名内部类】
1.匿名内部类其实就是内部类的简写格式。
2.定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3.匿名内部类的格式:new 父类或者接口(){定义子类对象};
4.其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解
为带内容的对象。
5.匿名内部类中定义的方法最好不要超过3个。
--------------------------
new AbsDemo(){
void show()
{System.out.println("");}
}.show();
--------------------------
AbsDemo ab = new AbsDemo(){
void show()
{System.out.println("");}
void show1(){}
};
ab.show();
ab.show1();//如果父类或者接口中没有show1方法,编译就错误;因为ab是父类引用。
练习:
interface Inner{
void method();
}
class Test
{//补足代码,通过匿名内部类
static Inner function(){
return new Inner(){
public void metnod(){
System.out.println("method run");
}
};
}
}
class InnerClassTest{
public static void main(String[] args){
Test.function().method();
}
}
//Test.function().method();
//Test.function():test类中有一个静态的方法function。
//.mehtod():function这个方法运算后的结构是一个对象,而且是一个Inner类型的对象。
//因为只有是Inter类型的对象,才可以调用method方法。
//Inter in = Test.function();
//in.method();
练习:
class InnerTest{
public static void main(String[] args){
new Object()//继承上帝{
public void function(){
}
}.function();
}
}
=====================================================
class Outer{
int x = 3;//用Outer.this.x
private class Inner//内部类 内部类可私有private{
int x = 6;//用this.x
void function(){
int x= 4;//内部有就打印内部的
System.out.println("Inner: "+x);
}
}
void method(){
Inner in = new Inner();
in.function();
}
}
class InnerDemo{
public static void main(String[] args) {
//Outer out = new Outer();
//out.method();
//直接访问内部类中的成员
//Outer.Inner in = new Outer().new Inner();
in.function();
}
}
//-----------------------------------------------------------
class Outer{
static int x = 3;
static class Inner//静态内部类 {
void function(){
System.out.println("Inner: "+x);
}
}
}
class InnerDemo{
public static void main(String[] args){
//直接访问内部类中的成员
//Outer.Inner in = new Outer().new Inner();
//in.function();
//在外部其他类中,如何直接访问静态内部类呢?用上面的方法就错误。
new Outer.Inner().function();
}
}
----------------------------------------------------------------------------------------------------------------------
异常
1.异常:就是程序在运行是出现不正确情况。
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。
对于问题的划分:两种:一种是严重的问题,一种非严重的问题。
对于严重的:java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。
对于非严重的:java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容,比如:不正常情况的信息,引发原因等。
Throwable//所有问题的超类。
|--Error
|--Exception
2.异常的处理
java提供了特有的语句进行处理
try{
需要被检测的代码
}
catch(异常类变量){
处理异常的代码:(处理方式)
}
finally{
一定会处理的代码;
}
3.对捕获到的异常对象进行常见方法操作
String getMessage():获取异常信息
在函数上声明异常。
便于提高安全性,让调用处进行处理,不处理会编译失败。
4.对多异常的处理。
(1).声明异常时,建议声明更为具体的异常,这样处理的可以更具体
(2).对方声明几个异常,就对应有几个catch块,不要定义多余的catch块
如果对个catch块中的异常出现异常关系,父类异常catch块放在最下面
建议在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句e.printStackTrace(),
也不要简单的就书写一条输出语句。
5.自定义异常
因为项目中会出现特有的问题。
而这些问题并未被java所描述并封装对象。
所以对于这些特有的问题可以按照java的对问题封装的思想
将特有的问题,进行自定义的异常封装
当要定义自定义异常的信息时,可以使用父类已经定义好的功能。
异常异常信息的传递给父类的构造函数。
自定义异常
需求:在本程序中,对于除数是负数,也视为是错误的是无法进行运算的
那么就需要对这个问题进行自定义的描述
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
要么在内部try catch处理
要么在函数上声明让调用者处理
一般情况下,函数内出现的异常,函数上需要声明。
发现打印的结果中只有异常的名称,没有异常的信息。
因为自定义的异常并未定义信息
【如何定义异常信息?】
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造函数,将异常信息传递给父类通过super语句
那么就可以直接通过getMessage方法获取自定义的异常信息。
自定义异常:必须是自定义类继承Exception
继承Exception类的原因:
异常体系有一个特点,因为异常类和异常对象都被抛出
他们都具备可抛性,这个可抛性是Throwable这个体系中独有特点。
只有这个体系中的类和对象才可以被throw和throws操作。
【throw和throws的区别】
throws使用在函数上
throw使用在函数内。
throws后面跟的异常类,可以跟多个,用逗号隔开
throw后跟的是异常对象。
【对于异常分两种】
1.编译时被检测的异常
2.编译时不被检测的异常,RuntimeException以及其子类
【finally】
finally代码块:定义一定执行的代码。
通常用于关闭资源。
finally只有一种情况不会执行,当执行到System.exit(0);finally不会执行
//记住一点:catch是用于处理异常,如果没有catch就代表异常内有处理过,
如果该异常是检测时异常,那么必须声明。
class FuShuException extends Exception{
private String msg;
FuShuException (String msg){
this.msg = msg;
}
public String getMessage(){
return msg;
}
}
class Demo
{
int div(int a,int b) throws FuShuException
{
if(b<0)
throw new FuShuException("不能输入负数!");
return a/b;
}
}
class ExceptionDemo{
public static void main(String[] args) //throws Exception{
Demo d = new Demo();
try {
int x = d.div(4,-1);
System.out.println(x);
}
catch(FuShuException e) {
System.out.println(e.toString());
System.out.println("不能输入负数!");
}
}
}
class FuShuException extends Exception{
FuShuException(String msg){
super(msg);//父类已经定义了该功能,所以就传给父类出做。
}
}
class Demo {
int div(int a,int b) throws FuShuException
{
if(b<0)
throw new FuShuException("不能输入负数!");
return a/b;
}
}
class ExceptionDemo{
public static void main(String[] args) //throws Exception{
Demo d = new Demo();
try{
int x = d.div(4,-1);
System.out.println(x);
}catch(FuShuException e){
System.out.println(e.toString());
System.out.println("不能输入负数!");
}
}
}
Exception中有一个特殊的子类异常RuntimeException,运行时异常,
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过,
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。
之所以不用在函数上声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况,
希望停止程序后,对代码进行修正。
自定义异常时,如果该类异常的发生,无法在继续进行运算,
就让自定义异常继承RuntimeException
class Demo {
int div(int a,int b) {
if(b<0)
throw new ArithmeticException("不能输入负数!");
return a/b;
}
}
class ExceptionDemo{
public static void main(String[] args){
Demo d = new Demo();
int x = d.div(4,-1);
System.out.println(x);
System.out.println("over");
}
}
异常在子父类覆盖中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。父类已经有问题了,子类只能抛父类的异常或者异常的子异常
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3.如果父类或者接口方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常,就必须要进行try处理,绝对不可以抛。
----------------------------------------------------------------------------------------------------------------------
包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰不同包中的子类还可以直接访问父类中被protected权限修饰的成员。
包与包之间可以使用的权限只有两种,public protected
public protected default private
同一个类中 ok ok ok ok
同一个包中 ok ok ok ok
子类 ok ok
不同包中 ok
注意:一个java文件中不能出现多个共有类
为了简化类名的书写,使用一个关键字:import
import导入的是包中的类
建议:不要写通配符*,需要用到包中的那个类,就导入那个类。
----------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com