java学习笔记
javase学习笔记之高级类特性
A1.面向对象三大特性:封装 继承 多态
1.封装: 一个类封装了数据以及操作数据的代码逻辑体。定义了数据的可访问属性(私有、公有)
Java中通过将数据声明为私有的(private),再提供公共的(public)方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的:使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作,便于修改,增强代码的可维护性;
2.继承 : 可以让一个类型获取另外一个类型的属性的方式。
概念:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。此处的多个类称为子类,单独的这个类称为父类(基类或超类)。可以理解为:“子类 is a 父类”
作用:继承的出现提高了代码的复用性。 继承的出现让类与类之间产生了关系,提供了多态的前提。 不要仅为了获取其他类中某个功能而去继承
重点:
(1)子类继承了父类,就继承了父类的方法和属性。
(2)在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。
(3)在Java 中,继承的关键字用的是“extends”,即而子类不是父类的子集,而是对父类的“扩展”。
(4)Java只支持单继承,一个子类只能有一个父类 一个父类可以有多个子类。
关于继承的规则: 子类不能直接访问父类中私有的(private)的成员变量和方法
3.多态 : 类实例的一个方法在不同情形下有不同的表现形式,即不同的外在行为。使具有不同的内部结构的对象可以共享相同的外部接口。
在java中有两种体现:
方法的重载(overload)和重写(overwrite)。 对象的多态性 ——可以直接应用在抽象类和接口上。
(1)Person p = new Student(); 向上转型;
p.walk();调用了学生的走路方法
Student s= Student(p);向下转型;利用强转符。
s.eat();调用了学生的吃饭方法
(2)程序分为编译状态和运行状态。
对于多态性来说,编译时“看左边”将此应用变量理解为父类类型,
运行时,“看右边”关注正真对象的实体,子类对象,那么执行的方法是子类重写的。
子类特有的 父类无法调用。
(3)多态的必要二个条件:1.继承 2.重写父类引用指向子类对象
(4)多态的实现方法:1.重写2.接口3.抽象类和抽象方法;
(5)子类的多态性并不适应于属性。
多态举例:
public class Test{
public void method(Person e) { //Person是Student父类;
//……
e.getInfo();
}
public static void main(Stirng args[]){
Test t = new Test();
Student s = new Student();
t.method(s); //子类的对象m传送给父类类型的参数e }
}
A2.重写与重载
1.重写:子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。
1)参数列表必须完全与被重写方法的相同;
2)访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。否则会有以下信息:Cannot reduce the visibility of the inherited method from Base
3)父类的成员方法只能被它的子类重写。
4)声明为final的方法不能被重写。
5)声明为static的方法不能被重写,但是能够被再次声明。(static和final的都不能被重写)
6)子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
7)子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
8)构造方法不能被重写。(构造方法属于static的)
9)如果不能继承一个方法,则不能重写这个方法。
Super关键字的使用
当需要在子类中调用父类的被重写方法时,要使用super关键字。
class Animal{
public void eat(){
System.out.println("动物可以吃饭");
}
}
class Dog extends Animal{
public void eat(){
super.move(); // 应用super类的方法
System.out.println("狗可以吃饭");
}
}
public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog 对象
b.eat(); //执行 Dog类的方法
}
}
2.重载:是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
重载规则:
被重载的方法参数个数或类型不一样;
被重载的方法可以改变返回类型;
被重载的方法可以改变访问修饰符;
方法能够在同一个类中或者在一个子类中被重载。
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//以下两个参数类型顺序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
A3.final:最终的。
基本用法:
1.可以修饰类: 被修饰的类不能被继承
2.可以修饰方法:方法不能被重写;基本类型:值不能改变,引用类型:地址值不能改变,对象中的属性可以改变。利用set方法
3.可以修饰变量: 修饰变量是final用得最多的地方,
!!!如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
public class car{
private final int i=1;
public car(){
int=2;//此时会报错
final Object ob=new Object();
ob=new Object();//会报错
}
}
通常与public static final 连用为全局常量 访问变得很方便,而且不会被修改。一般可以放配置信息,还有一些状态码的定义。
A4.static:静态的可以用来修饰属性方法,代码块(或初始化块),内部类,不能构造器。
static修饰属性(类变量):静态变量
1.由类创建的所有的对象,都公用一个属性,在内存中只有一个副本。
2.当其中一个对象对静态变量进行修改的时候,会导致其他对象对此属性的一个调用。 非静态变量又为实例变量(存在多个副本,各个对象拥有的副本互不影响)。
3.静态变量是通过类的创建而加载的。
4.静态变量可以通过“类.静态变量”的形式调用。
5.静态变量的加载要早于对象,当有对象的时候可以通过“对象.静态变量”调用,但是“类.非静态变量”不行(因为非静态变量随着对象的创建而加载,非静态变量的加载要晚于类的创建)
static修饰方法(静态方法)
1.随着类的创建而加载,在内存中也只有一份。
2.可以直接用“类.静态方法”调用。
3.在静态方法内部可以调用静态的属性跟方法,而不能调用非静态的属性方法。反之非静态的方法可以调用静态的属性跟方法。
4.因为静态方法不依附于任何对象,既然都没有对象,就谈不上this了。静态方法里面是不能有this和super关键字。
注:静态的结构(static的属性方法代码块内部类)的生命周期要早于非静态的结构。
static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。
static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
A5.抽象类与抽象方法(abstract):
抽象类是为了把相同的但不确定的东西的提取出来,为了以后的重用。定义成抽象类的目的,就是为了在子类中实现抽象类。
1.abstract修饰类:(1)不能被实例化(不能创建对象)。
(2)抽象类可以有构造器,也可以定义构造器。(凡是类都有构造器)
(3)抽象方法所在的类一定是抽象类。
(4)抽象类中可以没有抽象方法。一旦类中包含了abstract方法,那类该类必须声明为abstract类。
2.abstract修饰方法:
(1)格式:没有方法体 没有{ }如: public abstract void eat();
(2)抽象方法只保留功能,具体执行交给子类,由子类重写此抽象方法。
(3)若子类继承抽象类,没有重写所有的抽象方法,意味着自雷肯定还有抽象类,则子类必须声明抽象类才可以。
abstract class person(){
public abstract void eat();只保留了功能,具体实现交给子类。
public person(){
}//可以有构造器
}
class student extends person(){
public void eat(){
System.out.println("学生吃饭")
}
}
限制:不能abstract修饰属性 私有方法 构造器 final方法。
A6.接口(Interface):
在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
1.接口可以说是一个特殊的抽象类,是常量与抽象方法的一个集合。(不能包含变量和一般的方法)而类描述对象的属性和方法。接口要定义的一种功能,此功能会被类要实现的方法。
2接口不能用于实例化对象。接口没有构造方法。
3.接口中所有的方法必须是抽象方法。
4.实现接口的类,必须重写其中所有的抽象方法,方可实例化,若没有重写所有的抽象方法,则此类还是一个抽象类。
5.类可以实现多个接口------------Java中类的继承属于单继承
6.接口与接口之间属于继承关系,实现多继承
7.接口与具体实现类之间有多态性
特性:
1.接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
2.接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
interface AA{
int i=4;//所有的常量都是由public static final修饰
Boolean flag=false;
void method1();//抽象方法:所有的方法都是由public abstract修饰
void method2();
}
abstract class CC implements AA{
//若没有重写接口类的方法则此类必须是抽象类。
}
class BB implements AA{
public voidmethod1(){
}
public voidmethod2(){
}
}
interface DD{
void method3();
}
interface EE extends AA, DD{//接口中可以实现多继承。
void method1();
void method2();
void method3();
}