- 第1天
- 1.基础知识
- 2.static关键字
- 3.成员变量
- 4.继承
- 5.引用类型
bilibili视频链接: 黑马程序员13天进阶教程 第1天 1.基础知识
目标:快速复习基础知识
面向对象思想概述:
- Java是一种面向对象的高级编程语言。
- 面向对象:是用代码去高度模拟现实世界的事物,从而让软件为任务处理业务,为人类服务。
- 高级语言:代码看起来很像人类的自然语言。
面向对象最重要的两个概念:类和对象。
- 类是相同事物共同特征的描述。类只是学术上的一个概念并非真实存在的,只能描述一类事物。
- 对象:是真实存在的实例。实例==对象。
- 结论:有了类和对象就可以描述万千世界所有的事物。必须先有类才能有对象。
定义类:
-
格式:修饰符 class 类名{
}
-
注意:
- 1.类名的首字母建议大写。满足驼峰模式。 StudentNameCode
- 2.一个Java代码文件中可以定义多个类。但是按照规范还是建议一个Java文件定义一个类。
- 3.一个Java代码文件中,只能有一个类是用public修饰的,而且public修饰的类名必须成为当前Java代码的文件名称。
类中的成分:有且仅有五大成分(五大金刚)
修饰符 class 类名{
1.成员变量(Field): 描述类或者对象的属性信息的。
2.成员方法(Method): 描述类或者对象的行为信息的。
3.构造器(Constructor): 初始化一个对象返回。
4.代码块(后面学习的)
5.内部类(后面学习的)
}
类中有且仅有这五种成分,否则代码报错!
构造器:
格式:修饰符 类名(形参列表){
}
作用:初始化类的一个对象返回。
构造器的注意点:一个类默认自带一个无参数构造器,但是如果写了有参数构造器那么默认的无参数构造器就消失。
构造器初始化对象的格式:类名 对象名称 = new 构造器; Student s = new Student();
面向对象的三大特征:封装,继承,多态。
封装的哲学思维:合理隐藏,合理暴露。
封装最初的目的:提高代码的安全性和复用性,组件化。
封装的步骤:
- 成员变量应该私有。用private修饰,只能在本类中直接访问。
- 提供成套的getter和setter方法暴露成员变量的取值和赋值。
this关键字的作用:
- this代表了当前对象的引用。
- this关键字可以用在实例方法和构造器中。
- this用在方法中,谁调用这个方法,this就代表谁。
- this用在构造器,代表了构造器正在初始化的那个对象的引用。
示例:
package com.itheima._01知识回顾;
public class ClassDemo01 {
//类的五大成分
//1.成员变量(Field)
private String schoolName;
//2.成员方法(Method)
public String getSchoolName(){
return this.schoolName;
}
//3.构造器(Constructor)
public ClassDemo01(){
}
//4.代码块(后面学习)
{
schoolName = "黑马程序员";
}
//5.内部类(后面学习)
class Inner{
private String address;
}
System.out.println(123); //报错,因为类中有且仅有五大成分
public static void main(String[] args) {
//构造器返回类的一个对象
//无参构造器
People xiaoMing = new People();
xiaoMing.setName("小明");
xiaoMing.setAge(24);
System.out.println(xiaoMing); //包的权限名.对象的类型@(16进制地址) com.itheima._01知识回顾.People@6a5fc7f7
System.out.println(xiaoMing.getName() + ":" + xiaoMing.getAge()); //小明:24
//有参构造器 在初始化对象的时候为对象属性赋值
People xiaoHu = new People("小虎", 25);
System.out.println(xiaoHu); 包的权限名.对象的类型@(16进制地址) com.itheima._01知识回顾.People@73f792cf
System.out.println(xiaoHu.getName() + ":" + xiaoHu.getAge()); //小虎:25
}
}
class People {
private String name;
private int age;
public People(String name, int age) {
this.name = name;
this.age = age;
}
public People() {
}
public String getName() {
return name;
}
public void setName(String name) {
//谁调用这个方法,this就代表谁!!!
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.static关键字
目标:static关键字的概述。(重点)
引入:
- 我们之前定义了很多成员变量(name, age)
- 其实我们只写了一份,但是发现每个对象都可以用,这就说明
- Java中这些成员变量或者方法是存在属性的。
- 有些属性是属于对象的,有些是属于类本身的。
- Java是通过成员变量是否有static修饰来区分是类的还是属于对象的。
- static == 静态 == 修饰的成员(方法和成员变量)属于类本身的。
按照有无static修饰,成员变量和方法可以分为:
成员变量:
(1)静态成员变量(类变量)
有static修饰的成员变量称为静态成员变量也叫类变量,属于类本身的,
直接用类名访问即可。
(2)实例成员变量
无static修饰的成员变量称为实例成员变量,属于类的每个对象的,
必须用类的对象来访问。
成员变量内存图:
成员方法:
(1)静态方法
有static修饰的成员方法称为静态方法也叫类方法,属于类本身的,
直接用类名访问即可。
(2)实例方法
无static修饰的成员方法称为实例方法,
属于类的每个对象的,必须用类的对象来访问。
static修饰成员方法的内存原理:
小结:
成员变量有2种
-
有static修饰的属于类叫静态成员变量,与类一起加载一次,直接用类名调用即可。
-
无static修饰的属于类的每个对象的叫实例成员变量,与类的对象一起加载,对象有多少个,实例成员变量就加
载多少份。必须用类的对象调用。
成员方法有2种:
- 有static修饰的属于类叫静态方法,直接用类名调用即可。
- 无static修饰的属于类的每个对象的叫实例方法,必须用类的对象调用。
目标:成员变量的分类和访问。
按照有无static修饰成员变量分为:
(1)静态成员变量:有static修饰,属于类本身与类一起加载一次,直接用类名访问即可。
(2)实例成员变量:无static修饰,属于类的每个对象的,必须先创建对象,再用对象来访问。
成员变量的访问语法:
静态成员变量访问: 类名.静态成员变量。
实例成员变量的访问:对象.实例成员变量。
小结:
静态成员变量有static修饰,属于类本身,与类加载一次,因为只有一份所以可以被类和类的对象共享访问。
注意:不建议用对象访问静态成员变量,静态成员变量直接用类名访问即可!!!
实例成员变量,无static修饰,属于类的对象的,必须先创建对象,然后用对象来访问!
拓展:成员变量和成员方法访问的拓展。(面试常考)
方法:实例方法,静态方法。
成员变量:实例成员变量,静态成员变量。
8种访问形式的问答:
a.实例方法是否可以直接访问实例成员变量?可以的,因为它们都属于对象。
b.实例方法是否可以直接访问静态成员变量?可以的,静态成员变量可以被共享访问。
c.实例方法是否可以直接访问实例方法? 可以的,实例方法和实例方法都属于对象。
d.实例方法是否可以直接访问静态方法?可以的,静态方法可以被共享访问!
--------------------------------------------------------------------
a.静态方法是否可以直接访问实例变量? 不可以的,实例变量必须用对象访问!!
b.静态方法是否可以直接访问静态变量? 可以的,静态成员变量可以被共享访问。
c.静态方法是否可以直接访问实例方法? 不可以的,实例方法必须用对象访问!!
d.静态方法是否可以直接访问静态方法?可以的,静态方法可以被共享访问!!
实例:
package com.itheima._02static关键字;
public class StaticDemo {
//静态成员变量(类变量)
private static String schoolName = "黑马程序员";
//实例成员变量
private String name;
private int age;
//静态方法
public static String getSchoolName(){
return StaticDemo.schoolName;
//注意:如果是在本类中调用静态成员变量或静态方法,类名可以省略不写
//return schoolName;
System.out.println(name); //错误,静态方法不能访问实例成员变量
System.out.println(getAge); //错误,静态方法不能访问实例方法
}
//实例方法
public int getAge(){
//实例方法访问静态方法
System.out.println(getSchoolName());
//实例方法访问静态成员变量
System.out.println(schoolName);
return age;
}
}
4.继承
extends:使伸长;扩大;扩展;延长; 实际是子类在父类的基础上增强功能。
目标:继承(extends)的概述。
面向对象的三大特征:封装,继承,多态。
继承是Java中一般到特殊的关系,是一种子类到父类的关系。 例如:学生类继承了人类。猫类继承了动物类。
被继承的类称为:父类/超类。
继承父类的类称为:子类。
继承的作用:
可以提高代码的复用,相同代码可以定义在父类中。
然后子类直接继承父类,就可以直接使用父类的这些代码了。
子类更强大:子类不仅得到了父类的功能,它还有自己的功能。
继承的特点:
子类继承了一个父类,子类就可以直接得到父类的属性(成员变量)和行为(方法)了。
注意:子类无法访问父类中私有的属性和方法
继承的格式:
子类 extends 父类{
}
小结:
- 继承是子类到到父类的一种关系。
- 子类继承了一个父类,子类就可以直接得到父类的属性和行为了。
- 在Java中继承是 “is a” 的关系。Cat extends Animal:猫是一个动物。
- 在Java中,子类是更强大的,子类不仅继承了父类的功能,自己还可以定义自己的功能。
目标:了解子类能否继承父类的内容。
引入:
子类继承父类,子类就得到了父类的属性和行为。
但是并非所有父类的属性和行为等子类都可以继承。
子类不能继承父类的东西:
子类不能继承父类的构造器:子类有自己的构造器。(没有争议的)
有争议的观点(拓展):
子类是否可以继承父类的私有成员(私有成员变量,私有成员方法)?
---- 我认为子类是可以继承父类的私有成员的,只是不能直接访问而已。
----以后可以暴力去访问继承自父类的私有成员~~~
子类是否可以继承父类的静态成员?
---- 我认为子类是不能继承父类的静态成员的,
---- 子类只是可以访问父类的静态成员,父类的静态成员只有一份可以被子类共享访问。共享并非继承。
public class ClassDemo {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(Cat.schoolName);//黑马程序员
Cat.test();
c.run; //报错
}
}
class Animal{
public static String schoolName = "黑马程序员";
public static void test(){}
private void run(){};
}
class Cat extends Animal{
}
目标:继承的特点
单继承:一个类只能继承一个直接父类。
为什么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中的祖宗类!!
目标:继承后-成员变量的访问特点。
就近原则:
子类有找子类,子类没有找父类,父类没有就报错。
小结:
this代表了当前对象的引用,可以用于访问当前子类对象的成员变量。
super代表了父类对象的引用,可以用于访问父类中的成员变量,super.父类成员变量。
public class ClassDemo {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.name);//对象喵喵
cat.show();
}
}
class Animal{
public String name = "黑马程序员";
}
class Cat extends Animal{
public String name = "对象喵喵";
public void show(){
String name = "局部喵喵";
System.out.println(name); //局部喵喵
System.out.println(this.name);//对象喵喵
System.out.println(super.name);//黑马程序员
}
}
目标:方法重写。
方法重写的概念:
子类继承了父类,子类就得到了父类的某个方法
但是子类觉得父类的这个方法不好用或者无法满足自己的需求
子类重写一个与父类申明一样的方法来覆盖父类的该方法,子类的这个方法就进行了方法重写。
方法重写的校验注解: @Override
Java建议在重写的方法上面加上一个@Override注解。
方法一旦加了这个注解,那就必须是成功重写父类的方法,否则报错!
@Override优势:可读性好,安全,优雅!!
方法重写的具体要求:
1.子类重写方法的名称和形参列表必须与父类被重写方法一样。
2.子类重写方法的返回值类型申明要么与父类一样,要么比父类方法返回值类型范围更小。(以后再了解)
3.子类重写方法的修饰符权限应该与父类被重写方法的修饰符权限相同或者更大。(以后再了解)
4.子类重写方法申明抛出的异常应该与父类被重写方法申明抛出的异常一样或者范围更小!(以后再了解)
方法重写的规范:
1.加上@Override注解。
2.建议"申明不变,重新实现"。
小结:
方法重写是子类重写一个与父类申明一样的方法覆盖父类的方法。
方法重写建议加上@Override注解。
方法重写的核心要求:方法名称形参列表必须与被重写方法一致!!
建议"申明不变,重新实现"。
public class ClassDemo2 {
public static void main(String[] args) {
Man man = new Man();
man.run();
}
}
class People{
public void run(){
System.out.println("人会跑");
}
}
class Man extends People{
@Override
public void run() {
System.out.println("男人跑的很快");
}
}
目标:继承后-构造器的特点。
特点:
- 子类的全部构造器默认一定会先访问父类的无参数构造器,再执行子类自己的构造器。
为什么子类构造器会先调用父类构造器?
- 子类的构造器的第一行默认有一个super()调用父类的无参数构造器,写不写都存在!
- 子类继承父类,子类就得到了父类的属性和行为。
public class ExtendsDemo {
public static void main(String[] args) {
Dog jinMao = new Dog();
Dog jinMao1 = new Dog("金毛");
}
}
// 父类
class Animal{
public Animal(){
System.out.println("父类Animal的无参数构造器");
}
}
// 子类
class Dog extends Animal{
public Dog(){
// super(); //默认存在,即使不写:根据参数匹配调用父类无参数构造器。
System.out.println("子类Dog的无参数构造器");
}
public Dog(String name){
// super(); //默认存在,即使不写:根据参数匹配调用父类无参数构造器。
System.out.println("子类Dog的有参数构造器");
}
}
目标:super调用父类构造器。
特点:
- 子类的全部构造器默认一定会调用父类的无参数构造器。
- super(…):可以根据参数选择调用父类的某个构造器。
小结:
- 可以在子类构造器中通过super(…)根据参数选择调用父类的构造器,以便调用
package com.itheima._03继承;
public class ClassDemo2 {
public static void main(String[] args) {
Man man = new Man("黑马",20);
man.run(); //黑马:20
}
}
class Man extends People{
public Man(String name, int age) {
super(name, age);//根据参数调用父类的构造器
}
@Override
public void run() {
System.out.println(getName() +":"+ getAge());
}
}
class People{
private String name;
private int age;
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
public void run(){
System.out.println("人会跑");
}
//getter and setter
}
总结与拓展:this和super关键字使用总结
this代表了当前对象的引用(继承中指代子类对象):
this.子类成员变量。
this.子类成员方法。
this(…):可以根据参数匹配访问本类其他构造器。(还没有学习)
super代表了父类对象的引用(继承中指代了父类对象空间):
super.父类成员变量。
super.父类的成员方法。
super(…):可以根据参数匹配访问父类的构造器。
注意:
this(…)借用本类其他构造器。
super(…)调用父类的构造器。
this(…)和super(…)必须放在构造器的第一行,否则报错!
所以this(…)和super(…)不能同时出现在构造器中!!!
package com.itheima._03继承;
// 需求:希望如果不写学校默认就是”黑马“!
public class ClassDemo {
public static void main(String[] args) {
Cat cat = new Cat(1,"小花");
System.out.println(cat.getAge());
System.out.println(cat.getName());
System.out.println(cat.getSchoolName());
}
}
class Cat{
private int age;
private String name;
private String schoolName;
public Cat() {
}
public Cat(int age, String name) {
//借用兄弟构造器
this(age,name,"黑马程序员");
}
public Cat(int age, String name, String schoolName) {
this.age = age;
this.name = name;
this.schoolName = schoolName;
}
//getter and setter
}
5.引用类型
目标:引用类型作为方法参数和返回值。
引用类型作为Java的数据类型,自然可以作为方法的参数类型和返回值类型。
除了基本数据类型都是引用数据类型了。
关注语法即可!!
小结:
- 引用类型作为数据类型可以在一切可以使用类型的地方使用!!



