您的位置:首页 > 编程语言 > Java开发

面向对象JAVA基础笔记

2017-07-28 09:37 309 查看
面向对象笔记:

Super关键字:

-应用场景:当子类想要调用父类当中的属性,方法(构造方法?)时,用【super.】来区分。

-应用:当子类重写父类的属性或方法了,但又想调用父类的此属性或方法时。即可使用【super.】调用。

注意:super只能应用在成员方法和构造方法中,不能应用在静态方法中(和this是一样的),如果在构造方法中使用super(…)必须放在第一行。

This 和Super的区别:

-this和super都不能在static方法中调用



=============================================

访问控制权:



default ,和public 可以用来修饰类,但protected不能!

重写方法注意事项:

-在子类中可以根据需要对从父类中继承来的方法进行改造—-方法的重写/override

-重写方法必须和被重写方法具有相同的方法名称(大小写敏感)、形式参数列表和返回值类型

-重写方法不能使用比被重写方法更严格的访问权限

-父类的静态方法不能被子类覆盖为非静态方法,反之亦然

Overload and override:



================================================

final关键字:

·final类不能被继承,final方法不能被重写,final变量只能赋值一次;

·final不能修饰构造方法:因为构造方法不会被继承,更无所谓重写,所以就没有被修饰的必要了。且会编译会报错!

final,static,abstract修饰区别:



===========================================

关于抽象类:

-用abstract关键字修饰了的类就是抽象类!不管有没有抽象方法!

-不能被实例化,不是因为不能有构造方法

-抽象类可以没有任何方法,也可以有!

-但是如果含有抽象方法的类,就必须为抽象类,必须用关键字abstract修饰!

-抽象类之间能继承,且能实现父类的抽象方法!因为抽象类里可以有抽象方法和普通方法!

【错误观点:抽象类之间不能继承。(因为无法实现父类的抽象方法)xxxxxxxx】

关于抽象方法:

-抽象方法没有方法体,有抽象方法存在那么该类一定是抽象类!

-抽象方法必须在子类中被重写实现!。被重写后肯定就不是抽象方法了。

-构造方法和static方法不能是抽象的

接口:

可以看成是特殊的抽象类。这种抽象类只有常量属性和抽象的方法。也可以为空。

当子类继承抽象类或实现接口时,必须实现他们的所有的抽象方法!

-接口中的属性:默认为也必须为public static final,public可以不写,但是不能为其他访问权限。

-只能定义抽象方法: 修饰符必须且默认为public abstract,也可以缺省,但是不能为其他。

-什么时候用接口,什么时候用抽象类

 ·继承(实现)关系很简单时,可以用抽象类定义,(一些方法已经实现,而另一些方法无法或不想实现时,留给后面的代码去实现。)

 ·jdk1.8之后,可以在接口中定义default方法。

 ·当需要多继承时,就可以考虑用接口。单继承时,就考虑抽象类。

注意点:

一个接口可以有多个实现类,

一个类可以实现多个接口,

一个接口可以继承多个接口,

接口与抽象类的比较:



真的是实践出真知。! 只有自己写了几个类你才知道,他们的区别,用法!

-什么类型的【左边边定义的】引用对象就只能使用调用该类 的方法和属性,

包括其继承自父类公开的方法

-接口不能实例化,可以创建引用下下造型。同抽象类!

Teaching,Sport为接口,Person为抽象类,

Teacher,继承了抽象类,实现了Teaching的接口

Student_IA继承了抽象类,实现了sport 的接口。

Teaching teacher = new Teacher();

((Person) teacher).setName(“wangnima”);

Teaching per =new Student_IA(); //编译报错!

Teaching per = (Teaching) new Student_IA();//编译通过!运行不通过!会有强制转换异常!

-当你在造型的时候特别要注意。引用对象的类型是否有关系!!

Person stu = new Student_IA(); //学生类继承了抽象类Person ,造型成功。

Sports sport_stu3 = new Student_IA(); //学生类实现了接口Sport,造型成功!

多态 -. -

多态:即多种形态。

 好处是提高了代码的复用性。

 弊端是前期建立父类的引用,虽然可以接受所有的子类的对象,但是只能够调用父类的功能。不能够使用子类独有的功能。

因为在前期的程序当中并不知道后期想要添加的功能。但是可以调用子类重写父类的功能。

前提:

1,必须存在着继承关系。(或者实现关系)

2,通常会存在重写方法的操作。

对象的造型:

Dog d = new Dog();

Animal a = new Dog(); //———向上造型。

//好处提高代码的拓展性。坏处就是只能调用父类的方法(子类重写的方法)。不能调用子类特别的方法。

c = new Cat();

a和d的区别:d只能指向DOG对象,而a可以指向所有Animal 的对象。猫啊,猪啊,之类的。

d = (dog) a; //向下造型。需要强制转型(需要判断)。优点为可以使用子类特有的方法。

c = (cat ) a;//编译不报错,但是运行时会出现异常-类型转换异常。因为此时a为狗类,不能转换为毛类!

应用场景:

向上转型:当需要程序进行拓展,或者对象当中的方法进行限制时,就向上造型。操作其父类。

向下造型:当需要使用子类特有的功能时,就要向下造型。但是向下转型之前一定要判断是否为该类型的对象然后在转。

类型的判断:

关键字:instanceof()

判断的方式:对象.instanceof 类名。//表示该对象是否为该类的实例。返回布尔值。

误区:

Animal a = new Animal();

//在转型的过程当中,都是子类的对象作着类型的转换,千万不要把父类的对象转换成子类的类型。!!大错特错。

d = (dog)a;

多态在成员当中的特点:

先看如下代码的输出:

class Fu{
int x = 5;
public void show(){
System.out.println(
4000
"fu show run......");
}
public static void play(){
System.out.println("fu static play run......");
}
}
class Son extends Fu{
int x = 10;
public void show() {
System.out.println("zi show run......");
}
public static void play(){
System.out.println("zi static play run.........");
}
}
public class DuoTaiDemo {
public static void main(String[] args) {
Fu f = new Son();       //对象向上转型
System.out.println("x="+f.x);   //x=5
f.show();   //zi show run......
f.play();   //fu static play run......
}
}


1:成员变量

对于成员变量,在编译的时候时候,编译器阅读的是引用类型所属的类当中是否包含这个变量。如果包含,则编译通过。

否则,编译报错。

运行时期:调用的意识引用类型所属的类当中的成员变量。

简单来说,编译和运行都看等号左边的类型

2:成员函数

编译时期:编译器阅读引用类型所属的类当中时候包含这个方法,如果包含,编译通过,否则编译报错。

运行时期:查看所有所属的类当中是否包含这个方法,如果子类重写子类当中的方法,那么就调用子类重写的方法。

否则调用父类的方法。

原因:函数有重写的特性,子类可以重写父类当中的方法。

简单来说。编译看到等号左边的类型,运行看等号右边的类型。

3:静态成员函数

静态不需要绑定对象,他绑定的是对象所属的类。

非静态方法时需要调用这个方法的对象和当前方法进行绑定的。所有那个对象调用了方法,编译器就会去查看对象

的对象所属的类当中的放法

编译时期:编译器阅读引用类型所属的类当中是否包含这个静态函数,如果包含这个方法,编译通过。否则编译报错。

运行时期:调用引用类型所属的类当中的函数。

简单来说:编译和运行都看左边的类型。

这应该不属于面向对象了。但是也挺重要的!

Ingeter i1 = 1234;
Ingeter i2 = 1234;
i1 == i2;       //false
i1.equals(i2);     //true
---------------------------------------------------
Integer ii5= new Integer(123);
Integer ii6= new Integer(123);
Integer ii7= 123;
System.out.println(ii5 == ii6);  //false
System.out.println(ii5 == ii7);  //false
-------------------------------------
Ingeter i1 = 123;
Ingeter i2 = 123;
i1 == i2;           //true
i1.equals(i2);   //true
//这里涉及到一块缓存区,方法区当中的常量池。这个区域会缓存1byte之间的数据【-128,127】
//程序运行时都会加载到常量池当中。所以这区间数据的比较都是比较的基本数据类型。


String 基础必知

String类:

 -不可变的原因;

   private final char [] value;

   1,被final修饰,说明只能赋值一次,那么字符数组的引用地址就不能改变了

   2,被private修饰,并且没有实现公共的访问方式。那么自然的在外部类中无法访问 也无法修改了。

String 的操作就是对于字符数组的操作。

 -String 内存特点:

   java在运行时会维护生成一个String Pool(方法区当中的常量池),又叫字符串缓冲区。用于存储运行时产生的各种字符串。并且池中字符串不会重复!

   1,当任何方式创建字符串对象时,JVM都会在常量池中先查找时候有该对象。如果没有就会在池中先创建这个对象。

   2,java当中只要使用new关键字创建对象,就一定会在堆内存当中开辟空间。那么String的引用肯定指的就是堆内存中的地址

   3,如果不是使用new关键字创建字符串时,就不会区堆内存中开辟内存空间。即使用直接赋值,或字符串拼接,就只会在常量池中查找生成。

StringBuffer:可变的字符串序列,synchronized的修饰了方法,线程安全的。效率低。

StringBuilder:可变的字符串对象。线程不安全单效率高。用于单线程。使用更广泛。

这个类的对象可以添加元素后可以继续追加,因为他返回的就是它本身这个对象。就形成了方法链:

sb.append().append().append();

AbstractStringBuilder为这个两个类的父类。

在这两个类中,会通过expandCapacity()f方法改变数组的引用地址,扩充原来数组的长度。

这样就比String类内存优化了

成员变量才会有线程安全不安全的问题。

局部变量不会有该问题。

String的内存分析图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息