- 相对与之前学习过的C语言,Java最大的不同在于其面向对象的特性,这一点类似于最早介绍过的VB语言。抛开窗体和控件从VB到C语言 开发者创建完对象,而Java会帮助你完成各种操作,提供各种办法给程序开发带来便利。
- 面向对象的优点:
可重用性: 代码重复使用,减少代码量,提高开发效率。下面介绍的面向对象的三大核心特性(继承、封装和多态)都围绕这个核心。
可扩展性: 指新的功能可以很容易地加入到系统中来,便于软件的修改。
可管理性: 能够将功能与数据结合,方便管理。 - 面向对象编程是一种使用类和对象来设计程序的方法或模式。它通过提供一些概念简化了软件开发和维护:
提供的概念:- 面向对象概述
- 类
- 类的基础
- 成员变量和局部变量的不同
- static关键字和静态变量(类变量)
- 封装
- setXXX和getXXX
- this关键字
- 构造方法
- 构造方法的重载
- 成员变量的初始化和修改
- 继承
- 猫和狗继承动物案例
- Java继承的特点和注意事项
- super关键字
- 重写父类同名方法
- 多态
- 通过例题了解多态
- 向上转型和向下转型
- 抽象类
- 接口
- 类,接口的关系
- 接口实例(培养普通猫和跳高猫)
- 磊写在结尾
- Java中最基本的单位是类,类似于Java中用class描述事物。
- 而类的基本组成为成员变量(事物的属性)和成员方法(事物的行为)。如果类是一个人,那么成员变量就是人的年龄和性别这类人的特有属性。而成员方法就是人可以做的类似于吃饭睡觉的事情。
- 写完一个类后如何创建对象的格式:类名 对象名 = new 类名 ( ) ;
public class demo1{
public static void main(String[] args){
}
}
//定义一个类
class student{
String name;//成员变量
int age;
String gender;
public void study(){//成员方法
System.out.println("学生学习");
}
public void sleep(){
System.out.println("学生睡觉");
}
}
成员变量和局部变量的不同
- 在内存中的位置不同:
成员变量: 在堆内存(成员变量属于对象,对象进堆内存)
局部变量: 在栈内存(局部变量属于方法,方法进栈内存) - 生命周期不同:
成员变量: 随着对象的创建而存在,随着对象的消失而消失。
局部变量: 随着方法的调用而存在,随着方法的调用完毕而消失。 - 初始化值不同:
成员变量: 有默认初始化值
局部变量: 没有默认初始化值,必须定义,赋值,然后从才能使用。
- 被static关键字修饰的成语变量和成员方法独立于该类的任何对象。因而被类的所有共享(优先对象存在)例如我们定义水杯和饮水机,那么饮水机就可以用静态修饰,共享于整个类。如果不用static修饰,则代表你每创建一个对象,就给他一个饮水机,很浪费内存。
- 使用static注意事项: 我们无法从静态上下文中引用非静态。(静态只能访问静态,因为非静态不一定创造对象)例如:
class demo{
int num1=10;
static int num2=20;
public static void print2(){
System.out.println(num1);//会报错,无法使用非静态的num1
System.out.println(num2);
}
}
- 静态变量和成员变量的区别
- 定义: 用来隐藏对象的属性和实现的细节,仅对外提供公共访问方式,即私有。
- 现在让我们来介绍封装的一种表达形式,就是使用private关键字(权限修饰符),通过private定义后只能在本类当种进行访问。
- 那么在封装后,我们一定要通过setXXX 和 getXXX 两个函数对内部的数据进行调用。下面是一个简单的例子。
public class demo1{
public static void main(String[] args){
person p1=new person();
p1.name="张三";
p1.setAge(25);
int a=p1.getAge();
System.out.println(a);
}
}
//定义一个类
class person{
String name; //姓名
private int age; //年龄
//两个访问私有变量的方法
public void setAge(int a){
if(a>0 && a<120){
age=a;
}else{
System.out.println("你是什么怪物?");
}
}
public int getAge() {
return age;
}
}
this关键字
- 当我们的局部变量和成员变量重名时,可能会出现两个 age 这种情况,程序无法直接判断。所以我们需要通过一个this关键字来标记当前对象的成员变量。
class phone{
private String brand; //品牌
private int price; //价格
public void setBrand(String brand){
this.brand=brand;
}
public String getBrand() {
return brand;
}
public void setPrice(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
}
构造方法
- 概述: 如果你在类中写了一个与类同名的方法,那么我们在创建对象的时候就会自动使用方法。
- 构造方法的特点: a. 方法名与类名相同 b. 没有返回值类型,连 void 都没有 c. 没有具体的返回值return
- 构造方法的作用在于初始化对象
- 构造方法重载不同在于参数类型的不同。
public person(){};
//没有参数的叫做空参的构造。如果你不给类构造方法,那么系统会自动给一个空参的构造。
public person(String name,int age){
this.name=name;
this.age=age;
}
//有参的构造
成员变量的初始化和修改
- 了解构造方法和封装后,我们就会发现setXXX方法和构造方法的相同和不同点。很显然构造方法是用来初始化对象的,而setXXX方法是用来对属性进行修改的。
public class demo1{
public static void main(String[] args){
person p1=new person("张三",25);
}
}
//定义一个类
class person{
private String name; //姓名
private int age; //年龄
//构造方法
public person(){};
public person(String name,int age){
this.name=name;
this.age=age;
}
//两个访问私有变量的方法
public void setAge(int age){
this.age=age;
}
public int getAge() {
return age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
}
继承
- 继承是面向对象当中很重要的一点,它的存在让类与类之间产生了关系。子类通过继承可以拿到父类中的属性。
class cat{
String color;
int leg;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class dog{
String color;
int leg;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
- 在上面的例子中,我们定义了猫类和狗类,他们是不同的对象类型,但很显然他们的功能是一样的,那么我们能不能通过定义一个父类animal 来让猫和狗类去继承它呢,这样操作会让代码变得更为简洁。
好处: 1. 提高代码的复用性 2. 建立继承是多态的前提。
坏处: 1. 类的耦合性太强
public class demo1{
public static void main(String[] args){
cat a=new cat();
a.eat();
a.sleep();
dog b=new dog();
b.eat();
b.sleep();
}
}
class animal{
String color;
int leg;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class cat extends animal{
}
class dog extends animal{
}
Java继承的特点和注意事项
- 特点: 1. 只支持单继承,不支持多继承,表示一个儿子只有一个爹。2. 可以多层继承(儿子,父亲,爷爷)如果要观察共性,就看最顶层的类。
- 注意事项:
1. 子类只能继承父类所有非私有成员变量。如果父类被private私有后,那么就会加上get 和 set 方法,所以子类需要通过这类方法进行调用。
2. 子类不能继承父类的构造方法
3. 不要为了部分功能去继承
4. 子父类出现同名变量采用就近原则
- this.成员变量 调用本类成员变量,也可以调用父类
- super.成员变量 调用父类成员变量
- 注意事项: 每一个构造方法的第一条语句默认都是super ( ) ; 所以说子类的所有构造方法都会默认访问父类中的空参构造,记得完成父类的初始化。小知识: 所有类的最顶层都是object 类,父类默认访问object类中的空参构造 。
- 而super的作用就是用来调用父类的有参构造。 super(参数)
public class demo1{
public static void main(String[] args){
student s1=new student("张三",24);
s1.study();
}
}
//定义父类
class person{
private String name;
private int age;
//构造方法
public person(){}
public person(String name,int age){
this.name=name;
this.age=age;
}
//set和get
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//定义子类
class student extends person{
public student(){}
public student(String name,int age){
super(name,age);
}
public void study(){
System.out.println(getName() + "学习");
}
}
重写父类同名方法
- 当子类出现和父类同名的方法时。我们可以将父类内的方法进行重写操作,根据就近原则会按照子类的来。
- 举一个例子 父类代表Ios7系统,而我们子类要写一个Ios8系统,子类拥有父类大多数功能,但其中Siri 有更新了说中文的功能,那我们就可以对他进行重写。
public class demo1{
public static void main(String[] args){
ios8 phone=new ios8();
phone.siri();
}
}
class ios7{
public void call(){
System.out.println("打电话");
}
public void siri(){
System.out.println("说英语");
}
}
class ios8 extends ios7{
public void siri(){
System.out.println("说中文");//先输出说中文
super.siri();//在输出说英语
}
}
多态
- 表示事物存在的多种情况,多态需要三个前提。1. 要有继承关系 2. 要有方法重写 3. 父类引用指向子类的对象 Animal a = new cat();
1. 多态中的成员变量 ( 编译看父类,运行看父类 )
public class demo1{
public static void main(String[] args){
father f1=new son();//多态,父类引用指向子类对象
System.out.println(f1.num);//答案为10
son s1=new son();
System.out.println(s1.num);//答案为20
}
}
class father{
int num=10;
}
class son extends father{
int num=20;
}
2.多态中的成员方法 (编译看父类,运行看子类)
public class demo1{
public static void main(String[] args){
father f1=new son();//多态,父类引用指向子类对象
f1.print();//输出son
}
}
class father{
int num=10;
public void print(){
System.out.println("father");
}
}
class son extends father{
int num=20;
public void print(){
System.out.println("son");
}
}
通过例题了解多态
//该例子选自黑马程序员网课。讲述的是一个超人在和别人谈生意,然后碰到有人遇到危险,从窗户飞出去救人。
public class demo1{
public static void main(String[] args){
person p=new superMan(); //父类引用子类对象(他本质是一个超人,而我们用人定义了它,将超人提升为人) ->这被称之为向上转型
System.out.println(p.name); //多态中的成员变量,看父类 输出john
p.business(); //多态中的成员方法, 编译看父类有business,运行看子类,所以输出谈几个亿的大生意
//p.fly; 会发生报错!!!因为这是方法,方法首先看父类person类,没有找到fly所以会报错。
}
}
class person{
String name="john";//这是一个叫做john的人
public void business(){
System.out.println("谈生意");
}
}
class superMan extends person{
String name="superMan";
public void business(){
System.out.println("谈几个亿的大生意");
}
public void fly(){
System.out.println("飞出去救人");
}
}
向上转型和向下转型
- 现有向上转型才会有向下转型(类似于强制类型转换)
- 向上转型: person p= new superMan(); 父类引用子类对象就是向上转型,将超人提升为人。
- 向下转型: superMan sm = (superMan)p; 向下转型
而这个时候向下转型,就是john暴露他是超人,他就可以使用fly技能。sm.fly()
- 抽象类和抽象方法都要用abstract来修饰。
abstract class Animal{//抽象类
public abstract void eat();//抽象方法(存活在抽象类或接口中)
}
- 抽象类不能被实例化,既Animal a = new Animal (); 会发生报错。
- 重点: 抽象类可以借助具体的子类来实例化(抽象类多态)Animal a = new cat();
- 对于抽象类的子类: 要么仍然是抽象类 ,要么就要去重写抽象类中的所有抽象方法。
- 什么时候使用抽象类? 当你无法描述一个方法是,对于Animal ,我们就可以抽象成public abstract void eat(); 因为我们不知道每个不同的动物吃的是啥?
//在子类中进行重写
public void eat(){
System.out.println("猫吃鱼");
}
接口
- 关键字 interface 接口名{ } (接口的实现对标类的继承)
- 接口的注意事项:
- 接口所有的方法都是抽象的
- 常见形式:class 类名 implements 接口名{};
- 接口不能实例化(可以按照多态的方法来实例化)
- 接口的子类:可以是抽象类但意义不大。一般是具体类,需要重写接口中的所有抽象方法
- 接口因为没有实例化,不需要写构造方法。
- 接口中只有常量,定义变量也会默认为常量。public static final int num =10
- 成员方法只能是抽象方法。默认修饰符为public abstract
- 要记得加public,在重写中也是,因为接口是公共的
- 类与类: 单继承,多层继承
- 类与接口: 实现关系(implements)
既可以单实现,也可以多实现(因为方法是抽象的,即使同名也不需要担心)。接口就像干爹,同时能有多个干爹。
class demo implements Inter A, Inter B{//同时实现接口A和B
重写接口中的所有抽象方法
}
- 接口与接口: 继承关系(可以单继承,也可以多继承)
interface a extends b接口实例(培养普通猫和跳高猫)
public class demo1{
public static void main(String[] args){
cat c = new cat("普通猫",5);
c.eat();
c.sleep();
jumpcat jc=new jumpcat("跳高猫",3);
jc.eat();
jc.sleep();
jc.jump();
}
}
abstract class Animal{//抽象类
private String name;
private int age;
public Animal(){}
public Animal(String name,int age){
this.name=name;
this.age=age;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void eat(); //吃饭
public abstract void sleep(); //睡觉
}
//定义普通猫
class cat extends Animal{
public cat(){}
public cat(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("猫吃鱼");
}
public void sleep(){
System.out.println("侧着睡");
}
}
//定义跳高培训接口
interface jumping{
public abstract void jump();
}
//定义专门用来培训跳高的猫
class jumpcat extends cat implements jumping{
public jumpcat(){}
public jumpcat(String name,int age){
super(name,age);
}
public void jump(){
System.out.println("猫跳高");
}
}
磊写在结尾
- Java的学习内容仍然有很多,学习完需要总结所学的东西,并进行记录,才能巩固大量的新定义。



