面向对象思想概述:
Java是一种面向对象的高级编程语言。
面向对象:是用代码去高度模拟现实世界的事物,从而让软件为任务处理业务,为人类服务。
高级语言:代码看起来很像人类的自然语言。
面向对象最重要的两个概念:类和对象。
类是相同事物共同特征的描述。类只是学术上的一个概念并非真实存在的,只能描述一类事物。
对象:是真实存在的实例。 实例==对象。
结论:有了类和对象就可以描述万千世界所有的事物。
必须先有类才能有对象。
定义类:
格式:修饰符 class 类名{
}
注意:
1.类名的首字母建议大写。满足驼峰模式。 StudentNameCode
2.一个Java代码文件中可以定义多个类。但是按照规范还是建议一个Java文件定义一个类。
3.一个Java代码文件中,只能有一个类是用public修饰的,而且public修饰的类名必须成为当前Java代码的文件名称。
类的五大成分:
类中的成分:有且仅有五大成分
- 成员变量(全局变量)
- 成员方法
- 构造器
- 代码块
- 内部类
修饰符 class 类名{
// 1.成员变量(Field): 描述类或者对象的属性信息的。
// 2.成员方法(Method): 描述类或者对象的行为信息的。
// 3.构造器(Constructor): 初始化一个对象返回。
// 4.代码块
// 5.内部类
}
类中有且仅有这五种成分。
this关键字的作用:
this关键字可以用在实例方法和构造器中。
this代表了当前类的对象, this用在方法中,谁调用这个方法,this就代表谁。
this用在构造器,代表了构造器正在初始化的那个对象。
static关键字:
- 静态方法:有static修饰,属于类,直接用类名访问即可。
- 实例方法:无static修饰,属于对象的,必须用对象来访问。
- 静态成员变量有static修饰,属于类本身,与类加载一次,因为只有一份所以可以被类和类的对象共享访问。
- 注意:不推荐用对象访问静态成员变量,静态成员变量直接用类名访问即可!!!
- 静态方法属于类,有static修饰,直接用类名访问即可。
- 实例方法属于对象,无static修饰,必须先创建对象,然后用对象来访问。
- 静态方法也可以被对象共享访问,但是不推荐,因为静态方法直接用类名访问即可。
继承:
继承的作用?
- “可以提高代码的复用”,相同代码可以定义在父类中。
- 然后子类直接继承父类,就可以直接使用父类的这些代码了。(相同代码重复利用)
子类更强大:子类不仅得到了父类的功能,它还有自己的功能。
继承的特点:
子类继承了一个父类,子类就可以直接得到父类的属性(成员变量)和行为(方法)了。
继承的格式:
子类 extends 父类{
}
小结:
继承的优势可以把相同的代码定义在父类中,子类可以直接继承使用。
这样就可以提高代码的复用性:相同代码只需要在父类中写一次就可以了。
思考:子类能否继承父类的所有内容。
子类继承父类,子类就得到了父类的属性和行为。
但是并非所有父类的属性和行为等子类都可以继承。
子类不能继承父类的东西:
子类不能继承父类的构造器:子类有自己的构造器。(没有争议的)
有争议的观点(拓展):
子类是否可以继承父类的私有成员(私有成员变量,私有成员方法)?
— 我认为子类是可以继承父类的私有成员的,只是不能直接访问而已。
— 以后可以暴力去访问继承自父类的私有成员~~~
子类是否可以继承父类的静态成员?
— 我认为子类是不能继承父类的静态成员的,
— 子类只是可以访问父类的静态成员,父类的静态成员只有一份,只是可以被子类共享访问而已。共享并非继承。
super和this:
- this代表了当前对象的引用,可以用于访问当前子类对象的成员变量。
- super代表了父类对象的引用,可以用于访问父类对象中的成员变量。
继承后-成员方法的访问特点:
就近原则:
子类有找子类,子类没有找父类,父类没有就报错。
小结:
子类对象优先使用子类已有的方法。
方法重写:
子类继承了父类,子类就得到了父类的某个方法
但是子类觉得父类的这个方法不好用、或者无法满足自己的需求
子类重写一个与父类一样的方法来覆盖父类的该方法,子类的这个方法,就是进行了方法重写。
方法重写的校验注解: @Override
Java建议在重写的方法上面加上一个@Override注解。
方法一旦加了这个注解,那就必须是成功重写父类的方法,否则报错!
方法重写的具体要求:
1.子类重写方法的名称和形参列表 :必须与父类被重写方法一样。
2.子类重写方法的返回值类型: 要么与父类一样,要么比父类方法返回值类型范围更小。
3.子类重写方法的修饰符权限 :应该与父类被重写方法的修饰符权限相同或者更大。
4.子类重写方法申明抛出的异常:应该与父类被重写方法申明抛出的异常一样或者范围更小!
静态方法和私有方法是否可以被重写?
答: 都不可以.
继承后-构造器的执行顺序:
结论:
子类的任何构造器(有参、无参),默认一定会先执行父类的无参数构造器,再执行子类自己的构造器。
为什么子类构造器会先调用父类构造器?
1.因为子类的构造器的第一行,默认有一个super()方法,用来调用父类的无参数构造器,我们写不写,该方法默认都存在!
2.子类继承父类,子类就得到了父类的属性和行为。
当我们调用子类构造器初始化子类对象的时候,必须先调用父类构造器初始化父类对象的属性和行为。(PS:先有爸爸,才有儿子。)
class Animal{
public Animal(){
System.out.println("==父类Animal的无参数构造器==");
}
}
class Tiger extends Animal{
public Tiger(){
//super(); // 默认存在的,根据参数去匹配调用父类的构造器。
System.out.println("==子类Tiger的无参数构造器==");
}
public Tiger(String name){
//super(); // 默认存在的,根据参数去匹配调用父类的构造器。
System.out.println("==子类Tiger的有参数构造器==");
}
}
this和super关键字使用总结:
this:
this代表了当前对象的引用(继承中指子类对象);:
this.子类成员变量。
this.子类成员方法。
this(…):可以根据参数匹配访问本类其他构造器。
super:
super代表了父类对象的引用(继承中指父类对象)
super.父类成员变量。
super.父类的成员方法。
super(…):可以根据参数匹配访问父类的构造器。
this(…)和super(…):
- this(…)借用本类其他构造器。
- super(…)调用父类的构造器。
- this(…)和super(…)必须放在构造器的第一行,否则报错!
- 所以,this(…)和super(…)不能同时出现在构造器中!!!
疑问:
this(…)和super(…)不能同时出现在构造器中,那在上文中也讲到,子类的任何构造器中,都会默认有一个super()方法,这个不是矛盾了吗?
答:
//构造器1
public Student(String name , int age){
// 借用兄弟构造器的功能!
this(name , age , "黑马");
}
//构造器2:
public Student(String name, int age, String schoolName) {
//super(); //默认有该方法
this.name = name;
this.age = age;
this.schoolName = schoolName;
}
构造器1里边没有super()方法,因为它使用了this(…)借用了兄弟构造器,所以构造器1并没有真正的初始化对象,而是在兄弟构造器中初始化了对象,所以在兄弟构造器中,才会有默认的super()方法。
Java的单继承:
单继承:一个类只能继承一个直接父类。
为什么Java是单继承的?
答:反证法,假如Java可以多继承,请看如下代码:
class A{
public void test(){
System.out.println("A");
}
}
class B{
public void test(){
System.out.println("B");
}
}
class C extends A , B {
public static void main(String[] args){
C c = new C();
c.test(); // 出现了类的二义性!所以Java不能多继承!!
}
}
多层继承:一个类可以间接继承多个父类。
一个类可以有多个子类。
一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类!!