JAVA基础2

1、成员变量和局部变量

                    成员变量                           局部变量


作用范围    在该类中                           在函数内
所在位置    堆中,new对象时产生         在栈中
初始值        0或者null或者false           随机数,不初始化没办法使用


2、匿名对象
new Car().num = 5;
new Car().color = "red";
new Car().run();
//上面三个语句都是使用了匿名对象。但是注意了,三个是不同的对象,当执行完第一

//个语句后,这个对象就没有引用了,所以变垃圾了。


3、构造函数和构造代码块

(1)如果没定义构造函数,系统给你创建一个默认的 Person(){}
(2)如果定义了,系统就不会创建默认的了。
(3)构造函数在对象被创建的时候调用。

(4)构造代码块在创建对象时必然会调用,并且优先于构造函数

{
System.out.println("构造代码块");  //这里就是构造代码块的定义
}


4、this关键字,那个对象调用该函数,this就是那个对象。

Person(int age){

this.age = age;

}

当本类里的构造函数调用本类另外一个构造函数时,使用this();进行调用。

注意,this();必须是构造函数里的第一行

Person(String name,int age)
{
this(age); 
this.name = name;
}


5、static关键字

(1)static的成员变量和成员函数都是随着类的加载而加载的,生命周期最长。
    所谓的加载就是使用到这个类,比如 new Person();这个时候Person类就加载进内存
    还有Person.show();和在命令行中输入java hello这三种情况会加载类进内存
            但是,Person p这个语句只是定义,这个时候Person类并没有加载进内存

(2)static的变量是分配在数据段的

(3)static的成员优先于非static的成员存在

(4)静态的方法里不能调用非静态的成员变量和方法

(5)非静态的方法里能调用静态的和非静态的成员变量和方法

(6)静态方法里不能出现this,super这样的关键字,因为静态的本来就可以不需对象就能调用

(7)静态的数据时属于类的,而不属于某一个对象的,所以类名. 就能调用


6、静态代码块
//静态代码块在类加载进内存的时候执行
//当我们在命令行输入java StaticCode时,StaticCode类就加载进内存
//只有类加载的时候 静态代码块才能执行,并不是说new多少个对象就执行多少次
//然后JVM才开始调用main方法。
//输出结果是: b a c
public class StaticCode
{
static
{
System.out.println("b");
}
public static void main(String[] args)
{
System.out.println("a");
Test test = null;   //这个时候没有加载
new Test();   //这个时候Test类加载进内存
}
}
class Test
{
static
{
System.out.println("c");
}
}


7、JAVA内存分配图



8、内存执行过程分析:
Person p = new Person("zhangsan",18);
(1)把Person类加载进内存
(2)如果有静态代码块,则执行静态代码块
(3)在堆内存里开辟一块空间,分配内存地址
(4)成员变量默认初始化,name=null,age=0;
(5)成员变量显示初始化,name="lisi";
(6)构造代码块执行
(7)构造函数执行,name="zhangsan",age=18;
(8)把内存地址赋值给栈中的变量p


9、主函数
(1)静态的原因是 JVM直接可以通过类名调用
(2)参数(String[] args) 对应 命令行java HelloWorld haha heihei   里的 haha heihei


10、单例模式
(1)饿汉式,开发中用这种。
class SingleDemo{
//第一步,创建一个对象
private static SingleDemo single = new SingleDemo();
//第二步,构造函数私有化
private SingleDemo(){

}
//第三步,对外暴露获取本类对象的方法
public static SingleDemo getInstance(){
return single;
}
}
(2)懒汉式(延迟加载的设计模式),此方式存在弊端,多线程时有可能出现多个对象的存在。
class SingleDemo{
//第一步,创建一个对象
private static SingleDemo single = null;
//第二步,构造函数私有化
private SingleDemo(){

}
//第三步,对外暴露获取本类对象的方法
public static SingleDemo getInstance(){
if(single == null)
single = new SingleDemo();
return single;
}
}


11、继承
class Parent
{
int num = 4;
}
class Child extends Parent
{
int num = 5;
void show(){
int num = 6;
System.out.println(num);  
}
}
class Demo{
public static void main(String[] args){
Child c = new Child();
//就近原则,结果是6。如果没有局部变量,那么结果是5。
//this.num 那结果就是5。
//super.num 那结果是4。
//this是当前的对象
//super不是父类的对象,而是父类的内存空间。
c.show();
}
}


12、重写
(1)重写的方法中,子类的权限必须大于等于父类的该方法的权限
(2)静态只能覆盖静态,因为优先于对象存在。


13、继承中构造函数特点:子类的构造函数里,第一行有一个隐式的super()调用父类的构造函数。如果父类里没有默认的构造函数,而子类中的构造函数也没有显式调用,那必然会报错。


14、final关键字
final修饰的类不能被继承
final修饰的方法不能被重写
final修饰的变量(成员变量和局部变量)是常量,不能再赋值。


15、abstract抽象类
(1)声明为抽象方法,那么该类就必须为抽象类。
(2)抽象类不能new对象,谁继承了抽象类,必须重写。
(3)当然,如果一个抽象类继承了一个抽象类,那么该抽象类不用重写抽象方法,但是只要后面的不是抽象类的 继承了该抽象类,那么就要重写里面的所有抽象方法。
abstract class Person{
abstract void show();
}



16、接口interface,其就是一个特殊的抽象类
interface Inter
{
public static final int a = 5;     //接口里的变量都是public static final修饰的
public abstract void show();   //接口里所有的抽象方法都是public修饰的
public abstract void display();
}  //同样,实现接口,就要重写里面的所有的抽象方法。
(1)类与类之间是继承关系。
(2)类与接口之间是实现的关系。
interface A
{
public abstract void show();
}
interface B
{
public abstract void display();
}
class C
{
public void func(){}
}
class D extends C implements A,B  //多实现,重写里面的所有抽象方法
{
public void show(){}
public void display(){}
}
(3)接口与接口之间是继承关系(可以多继承)。
interface A
{
}
interface B
{
}
interface C extends A,B  //接口之间的多继承
{
}


17、多态
成立条件:
(1)有继承关系
(2)方法重写
(3)父类引用指向子类对象
abstract class A
{
abstract void eat();
}
class B extends A
{
public void eat(){
System.out.println("B");
}
public void show(){
System.out.println("B show");
}
}
class C extends A
{
public void eat(){
System.out.println("C");
}
public void display(){
System.out.println("C display");
}
}
public class Test
{
public static void main(String[] args){
A a1 = new B(); //多态,向上转型
A a2 = new C();
a1.eat(); //调用B里的eat方法
a2.eat(); //调用C里的eat方法
a1.show(); //不行,show是子类特有的方法,a1是A类型,所以看不到该方法
a2.display(); //不行,理由同上
//要想调用子类里特有的方法,怎么办?
B b = (B)a1;  //向下转型
b.show(); //这样就可以调用了,因为现在b是B类的对象
}
}


18、多态的特点
(1)成员变量,看左边,左边有,那就执行。
class A{
int num = 5;
}
class B extends A{
int num = 6;
}
class Demo{
public static void main(String[] args){
A a = new B();
a.num; //结果是 5
}
}
(2)成员函数,还是看左边,执行的的时候如果发现show方法重写了,就会执行子类show的方法
class A{
void show(){
System.out.println("A run...");
}
}
class B extends A{
void show(){
System.out.println("B run...");
}
}
class Demo{
public static void main(String[] args){
A a = new B();
a.show();  //结果是 B run
}
}
(3)静态成员,还是看左边,因为很对象没有关系。
class A{
static void show(){
System.out.println("A run...");
}
}
class B extends A{
static void show(){
System.out.println("B run...");
}
}
class Demo{
public static void main(String[] args){
A a = new B();
a.show();  //结果是 A run
}
}

19、instanceof关键字
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
void eat(){
System.out.println("cat eat");
}
}
class Dog extends Animal
{
void eat(){
System.out.println("dog eat");
}
}
public class Test
{
public static void main(String[] args)
{
Animal a1 = new Cat(); //这句话可理解为:a1实际是一只猫,我们叫它为动物
Animal a2 = new Dog();
Dog d = new Dog();
System.out.println(a1 instanceof Cat);  //true     a1是一种猫吗?
System.out.println(a1 instanceof Animal); //true   a1是一种动物吗?
System.out.println(a1 instanceof Dog); //false
System.out.println(d instanceof Dog);  //true
System.out.println(d instanceof Animal); //true     d是一种动物吗?
}
}


20、equals的用法
class Demo
{
String name;
Demo(String name){
this.name = name;
}
public boolean equals(Object obj){  //重写Object类里的equals方法
if(obj instanceof Demo){    
Demo d = (Demo)obj;   //向下转型,获得Demo里的成员变量name
return this.name == d.name;
}else{
return false;
}
}
}
public class EqualsDemo
{
public static void main(String[] args){
Demo d1 = new Demo("hello");
Demo d2 = new Demo("world");
System.out.println(d1.equals(d2));  //false
}
}


21、getClass(),获得该对象所属的字节码对应的类文件对象。
通过这个对象就能获取这类的一些相关信息,比如成员变量,方法等。


22、面试题:
//结果为false
//首先在常量区里有个" abc "字符串,把trim运算后的结果赋值给s1,
//注意了,此时常量区里还没有"abc",只有" abc "
//当出现另外一个常量"abc"时,他们明显代表的是不同的常量
public class Test
{
public static void main(String[] args){
String s1 = " abc ".trim();
System.out.println(s1 == "abc");  
}
}


23、内部类
(1)内部类可直接访问外部类的所有成员,包括私有的成员变量和成员方法
(2)外部类不能直接访问内部类的成员,若想访问,必须通过对象。通过对象也能访问到内部类的私有成员。
(3)其他类访问内部类的方法,Outer.Inner inner = new Outer().new Inner();
(4)Inner类是可以被private修饰的,因为它出现在Outer类的成员位置
(5)假如有外部类的成员变量x=5,内部类的成员变量x=6,内部类的function方法的
局部变量x=7。那么在function里执行System.out.println(x)是输出7
执行System.out.println(this.x)是输出6
执行System.out.println(Outer.this.x)是输出5
从此也可以得到一个结果,内部类可以直接访问外部类的成员,其实就是省略
写Outer.this.x
class Outer
{
int x = 5;
class Inner
{
void function(){
System.out.println(x);  //对应于上面的(1)
}
}
void show(){              
Inner in = new Inner();  //对应于上面的(2)
in.function();           
}
}
public class Test
{
public static void main(String[] args){
Outer.Inner inner = new Outer().new Inner(); //对应于上面的(3)
inner.function();   
}
}
/******************************************************************************/
静态内部类
(1)由于内部类在外部类里的位置是成员,所以可以用static来修饰
(2)静态内部类只能访问外部类里静态的成员
(3)其他类访问静态内部类的方式Outer.Inner in = new Outer.Inner();
(4)静态内部类里的成员可以是静态的,也可以是非静态的
(5)非静态的内部类里的成员只能是非静态的。
class Outer
{
private static int x = 5;
static class Inner
{
void function(){
System.out.println(x);
}
}
}
public class Test
{
public static void main(String[] args){
Outer.Inner in = new Outer.Inner();
in.function();
}
}
/******************************************************************************/
内部类出现在局部变量的位置
(1)同样可以直接访问外部类的成员
(2)要想访问所在方法里的局部变量,只能加final来修饰
(3)此内部类不能被private static等关键字修饰,因为是局部变量
class Outer
{
int x = 5;
void show(){
int y = 6;
class Inner
{
void function(){
System.out.println(x); //如(1)所说,没问题
System.out.println(y); //如(2)所说,有问题,y必须是final
}
}
new Inner().function();
}
}
public class Test
{
public static void main(String[] args){
new Outer().show();
}
}


24、匿名内部类
abstract class Demo
{
abstract void show();
}
class Outer
{
int x = 5;
void function(){
new Demo(){      //可以理解为,有一个类继承于Demo,创建该类的对象。
void show(){  //这个子类重写了父类的抽象方法
System.out.println(x);
}
}.show(); //执行里面的方法
}
}


25、修饰符的访问权限
------------------------------------------------------------ 
                        类内部     package内       子类         其他 
public           允许         允许         允许         允许 
protected        允许         允许         允许        不允许 
default          允许         允许        不允许       不允许 
private          允许        不允许       不允许       不允许 
------------------------------------------------------------- 


26、异常
try{

}catch(Exception e){
//异常时执行
}finally{
//一定会执行
}
throws关键字:如果一个函数使用该关键字,那表明往外抛异常,当调用该函数的
时候,必须捕获处理。当然你也如果不想处理可以继续往外抛
throw关键字:自定义异常,相当于用这个关键字能产生一个异常
class MyException extends Exception
{


}
class Demo
{
int show(int a) throws MyException{ //然后往外抛才算是完成一个自定义的异常
if(a == 0){
throw new MyException(); //自定义产生一个异常
}else{
return a;
}
}
}
//注意:RunTimeException可以不用try catch,也可以不用throws


27、包
package pack;
public class PackageDemo
{
public static void main(String[] args){
System.out.println("hello world");
}
}
dos命令窗口:
E:\java_project> javac -d . PackageDemo.java  ==>当前目录即(E:\java_project目录)
下生成了一个整体,这个整体是文件夹名字为pack,里面有一个PackageDemo.class文件


E:\java_project> java pack.PackageDemo  ==>执行,要写全称
//注意,如果不想在当前目录下生成class文件,那么可以在-d后指定自己设定的路径
//但是执行的时候就要主要classpath的问题了


28、import关键字
为了简化b.packageB test = new b.packageB();写法
import b.packageB;
packageB test = new packageB();


29、打包JAR文件
jar包:打包命令 jar -cvf haha.jar a b   //把a b目录下的class文件打包为haha.jar
jar包的使用,直接将jar包的路径设到classpath里
比如在C盘的根目录下有一个haha.jar包
set classpath=c:\haha.jar   就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值