类其实就是一个模板,比如说类就好比一张房子的设计图纸,或者说是一个倒印模具,创建一个类就好比设计一张图纸,刻一个模板。对象就好比一座建好的房子,一个成型的模型,无疑想要一座房子或者一个模型都先需要一张图纸和一个模板,而这就是类和对象的关系。
首先Java里面的类由关键字class定义,类中的元素称为:成员属性。类中的函数称为:成员方法。
class Person {
public int age;//成员属性 实例变量
public String name;
public String sex;
public void eat() {//成员方法
System.out.println("吃饭!");
}
public void sleep() {
System.out.println("睡觉!");
}
}
再去定义一个类
class Person {
public String name;
public String sex;
public int age;
//....人的属性
}
然后拿这个类创建一个对象,然后我们可以通过点号 . 来访问这个对象的成员,看下图
Person person = new Person();//实例化一个对象
public && private
在类的定义中有许多的访问权限修饰符,而public和private是两个最常使用的,顾名思义,public修饰的变量是公开的,所谓的公开就是说可以直接访问,举个栗子
当我们使用public修饰成员变量时可以正常使用,通过点号访问对象的成员,但是当我们使用private修饰的时候,就会报错,因为private是私有的,只能在当前类里面使用,不能被外部引用。
当我们使用public修饰成员变量时可以正常使用,通过点号访问对象的成员,但是当我们使用private修饰的时候,就会报错,因为private是私有的,只能在当前类里面使用,不能被外部引用。
1.建议实现类的时候将成员变量尽量设置为private属性,防止数据被直接篡改,而方法非必要公开的接口也设置为private属性的,具体根据实际情况来定
2.变量名和方法名使用小驼峰命名规则,尽量做到见名知意,做不到应该给上适当的中文注释,帮助其他人理解代码的意思
3.static修饰的代码和代码块优先于任何代码执行
4.一个类可以创建多个对象,很好理解,一张图纸可以建造多栋相同的房子,比如小区的楼房就是一张图纸建造出来的
5.在实例化一个对象的时候会调用一个构造方法,所谓的构造方法就一个名字与类名相同的方法,可以带参数,没有返回值类型声明,并且如果你没有定义的话,编译器就会自动实现一个不带参数的构造方法,如果你定义了,那么编译器就不会自动生成。并且构造方法也是支持重载的,构造方法的用处之一就是可以在创建对象的时候就进行赋值
类与对象
一:类是什么
类是一种用户自定义的数据类型
包含
一、属性:数据
二、行为:函数
总的来说类里面有数据和函数
二、对象是什么:
使用类类型定义的变量
三、类和对象的关系
类是对象的抽象(归纳总结)
对象是类的具体(实例)
类是具有相同属性和行为的对象的集合
对象是有具体数据值的类
类成员访问属性修饰关键字
公有属性 public
私有属性 private
保护属性 protected
如果在定义类的时候没有写这些,那么类成员就会被系统默认为是私有属性
访问属性修饰关键字是可以无限次使用的,可以随意转换属性,每一个修饰关键字的范围是截止到下一个修饰关键字
class 类名称 {
属性 (变量) ;
行为 (方法) ;
}
例如我定义一个person类
class Person { // 类名称首字母大写
String name ;
int age ;
public void tell() { // 没有static
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
}
类定义完成之后,肯定无法直接使用。如果要使用,必须依靠对象,那么由于类属于引用数据类型,所以对象的产生格式(两种格式)如下:
(1)格式一:声明并实例化对象
类名称 对象名称 = new 类名称 () ;
(2)格式二:先声明对象,然后实例化对象:
类名称 对象名称 = null ;
对象名称 = new 类名称 () ;
引用数据类型与基本数据类型最大的不同在于:引用数据类型需要内存的分配和使用。所以,关键字new的主要功能就是分配内存空间,也就是说,只要使用引用数据类型,就要使用关键字new来分配内存空间。
当一个实例化对象产生之后,可以按照如下的方式进行类的操作:
对象.属性:表示调用类之中的属性;
对象.方法():表示调用类之中的方法。
范例:使用对象操作类
package com.wz.classandobj;
class Person {
String name ;
int age ;
public void get() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class TestDemo {
public static void main(String args[]) {
Person per = new Person() ;// 声明并实例化对象
per.name = "张三" ;//操作属性内容
per.age = 30 ;//操作属性内容
per.get() ;//调用类中的get()方法
}
}
输出结果是张三30
倘若package com.wz.classandobj;
class Person {
String name ;
int age ;
public void get() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class TestDemo {
public static void main(String args[]) {
Person per = null;//声明对象
//per = new Person() ;//实例化对象
per.name = "张三" ;//操作属性内容
per.age = 30 ;//操作属性内容
per.get() ;//调用类中的get()方法
}
}
则其运行结果位
Exception in thread "main" java.lang.NullPointerException
at com.wz.classandobj.TestDemo.main(TestDemo.java:15)
此时,程序只声明了Person对象,但并没有实例化Person对象(只有了栈内存,并没有对应的堆内存空间),则程序在编译的时候不会出现任何的错误,但是在执行的时候出现了上面的错误信息。这个错误信息表示的是“NullPointerException(空指向异常)”,这种异常只要是应用数据类型都有可能出现
关于继承
首先明白
为什么要继承
继承可以降低代码编写的冗余度,提高编程的效率。通过继承,子类获得了父类的成员变量和方继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承的作用:通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类{
... //成员变量、成员方法
}
class 子类 extends 父类{
... //类体
}
class teacher{ //声明一个teacher类为父类
String name; //定义父类的成员变量name、age
int age;
void show(){ //定义父类成员方法,将成员变量输出
System.out.println(name);
System.out.println(age);
}
}
class Student extends teacher { //声明一个Student类为子类并继承父类
}
public class myfirst {
public static void main(String[] args) {
System.out.println("学生");
Student student=new Student(); //声明一个Student类的实例对象student
student.name="Tom"; //子类调用父类的成员变量name并赋值
student.age=19; //子类调用父类的成员变量age并赋值
student.show(); //子类调用父类的成员方法show
}
}
那么其结果输出为
学生
Tom
19
且其有几个环节需要去考虑
子类不能选择性继承父类;
Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;
构造方法不会被子类继承,但可以从子类中调用父类的构造方法。
继承的优点
继承过来的字段和方法,可以像任何其他字段和方法一样被直接使用;
在子类中可以声明一个与父类中同名的新字段或静态方法,从而“隐藏”父类中的字段或方法;
可以在子类中声明一个在父类中没有的新字段和方法;
可以在子类中编写一个父类当中具有相同名的新实例方法,这称为“方法重写”或“方法覆盖”;
可以在子类中编写一个调用父类构造方法的子类构造方法,既可以隐式地实现,也可以通过使用关键字super来实现。
以及子类重写父类方法
子类定义一个静态型方法后
隐藏父类方法
以及还有使用super调用父类的方法
无参数构造方法or有参数构造方法
子类不继承其父类的构造方法。
当使用无参数的super()时,父类的无参数构造方法就会被调用;
当使用带有参数的super()方法时,父类的有参数构造方法就会被调用。
例如:class SuperClass { //创建父类SuperClass
private int n; //声明一个私有变量n
SuperClass(){ //父类无参数构造方法
System.out.println("这是父类SuperClass无参数构造方法");
}
SuperClass(int n) { //父类有参数构造方法
System.out.println("这是父类SuperClass有参数构造方法");
this.n = n;
}
}
class SubClass extends SuperClass{ // SubClass类继承SuperClass类
private int n; //声明一个私有变量n
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("这是子类无参数构造方法");
}
public SubClass(int n){ //子类有参数构造方法
super(300); //调用父类中带有参数的构造器
System.out.println("这是子类有参数构造方法"+n);
this.n = n;
}
}
public class myfirst {
public static void main(String[] args) {
SubClass sc1 = new SubClass(); //创建子类SubClass实例对象,调用其无参数构造方法
SubClass sc2 = new SubClass(100); //创建子类SubClass实例对象,调用其有参数构造方法
}
}
在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。
在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。在程序中,如果想声明一个类继承另一个类,需要使用extends关键字。
通过 extends 关键字让类与类之间产生继承关系。
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。
注意事项:
子类可以直接访问父类中的非私有的属性和行为。
子类无法继承父类中私有的内容。
父类怎么来的?共性不断向上抽取而来的。class Person{
String name;
int age ;
}
class Student extends Person{
void study(){
System.out.println("student study..." + age);
}
}
class Worker extends Person{
void work(){
System.out.println("worker work..." + age);
}
}
class ExtendDemo{
public static void main(String[] args){
Student s = new Student();
s. name = "zhangsan" ;
s. age = 20;
s.study();
Worker w = new Worker();
w. name = "lisi" ;
w. age = 30;
w.work();
}
}
好处:
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
继承的特点
在类的继承中,需要注意一些问题,具体如下:
1.在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类,例如下面这种情况是不合法的。
2.多个类可以继承一个父类,例如下面这种情况是允许的。
3.在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类,例如C类继承自B类,而B类又可以去继承A类,这时,C类也可称作A类的子类。例如下面这种情况是允许的。
4.在Java中,子类和父类是一种相对概念,也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如上面的示例中,B类是A类的子类,同时又是C类的父类。
Java只支持单继承,不支持多继承。一个类只能有一个父类,不可以有多个父类。
原因:因为多继承容易出现问题。两个父类中有相同的方法,子类到底要执行哪一个是不确定的。
super关键字&函数覆盖
在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型。
当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,在Java中专门提供了一个super关键字用于访问父类的成员。例如访问父类的成员变量、成员方法和构造方法。
在子父类中,成员的特点体现:
成员变量
this和super的用法很相似
this代表本类对象的引用super代表父类的内存空间的标识
当本类的成员和局部变量同名用this区分
当子父类中的成员变量同名用super区分父类
super代表父类的内存空间的标识
当本类的成员和局部变量同名用this区分
当子父类中的成员变量同名用super区分父类
官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
我的解释:接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。或者我们可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方 就像一个类一样,一个接口也能够拥有方法和属性,但是在接口中声明的方法默认是抽象的。(即只有方法标识符,而没有方法体)。
接口指明了一个类必须要做什么和不能做什么,相当于类的蓝图。
一个接口就是描述一种能力,比如“运动员”也可以作为一个接口,并且任何实现“运动员”接口的类都必须有能力实现奔跑这个动作(或者implement move()方法),所以接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。
如果一个类实现了一个接口中要求的所有的接口的类都必须有能力实现奔跑这个动作(或者implement move()方法),所以接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。
如果一个类实现了一个接口中要求的所有的方法,然而没有提供方法体而仅仅只有方法标识,那么这个类一定是一个抽象类。(必须记住:抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类)
一个JAVA库中接口的例子是:Comparator 接口,这个接口代表了“能够进行比较”这种能力,任何类只要实现了这个Comparator接口的话,这个类也具备了“比较”这种能力,那么就可以用接口的语法实现
为了声明一个接口,我们使用interface这个关键字,在接口中的所有方法都必须只声明方法标识,而不要去声明具体的方法体,因为具体的方法体的实现是由继承该接口的类来去实现的,因此,接口并不用管具体的实现。接口中的属性默认为Public Static Final.一个类实现这个接口必须实现这个接口中定义的所有的抽象方法。
一个简单的接口就像这样:拥有全局变量和抽象方法。
来进行排序操作了。为什么要用接口
接口被用来描述一种抽象。
因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限。
接口也被用来实现解耦。
接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。为什么要用接口
接口被用来描述一种抽象。
因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限。
接口也被用来实现解耦。
接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。
接口我们可以看做是抽象类的一种特殊情况,在接口中只能定义抽象的方法和常量:
1.在Java中接口用interface声明
2.接口中的方法都是public abstract的不能更改
3.接口中的变量默认都是public static final 类型的,不能更改,所以必须显示初始化
4.接口不能被实例化,接口中没有构造函数的概念
5.接口之间可以继承,但接口之间不能实现
6.接口的方法只能通过类实现,通过implements关键字继承
7.如果一个类实现了接口,那么接口中的所有方法必须实现(抽象类在实现接口时时可以将方法再定义成抽象方法)
8.一个类可以实现多个接口
使用接口的好处
采用接口明确的声明了它所能提供的服务
解决了就Java单继承的问题
实现了可接插性
接口和抽象类的区别?
a) 接口描述了方法的特征,不给出实现,一方面解决 java 的单继承问题,实现了强大
的可接插性
b) 抽象类提供了部分实现,抽象类是不能实例化的,抽象类的存在主要是可以把公共的
代码移植到抽象类中
c) 面向接口编程,而不要面向具体编程(面向抽象编程,而不要面向具体编程)
d) 优先选择接口(因为继承抽象类后,此类将无法再继承,所以会丧失此类的灵活性)
类之间的关系
在java中,接口不是类,而是对符合这个接口的类的一组需求
接口用interface声明
声明一个Comparable接口
可以将接口看成一个没有实例字段的抽象类
public interface Comparable {
声明一个方法,方法的实现由实现这个接口的类来实现方法
接口绝不会有示例字段,在java8以前,在接口中绝对不会实现
方法。
private int data://error
int compareTo();//OK
}
类实现接口
将类声明为实现某个接口用implements关键字
class Person implements Comparable {
在实现接口的类中必须实现接口中的方法,必须用public声明
public int compareTo() {
}
}
接口
- 类: 类别
- 具有相同属性、行为方式
## 抽象:
- 类是不是抽象的?4r5
- 类相对于对象抽象的
- 类中的方法是具体的 > 逻辑 运算
```java
//门
public class Door{
public void open(){
System.out.println("拔下门闩,开门!");
}
public void close(){
System.out.println("插上门闩,关门!");
}
}
class Manage{
public static void main(String[] args){
Door door = new Door();
door.open();
door.close();
}
}
```
- 上面的门如果需要升级扩展开关,那么就需要修改门的源代码
## 接口: interface
- 格式: public interface 接口名{ }
- 接口中可以定义 属性 以及方法
- 属性: 默认由 static final 修饰
- static: 静态的 唯一
- 唯一: 在整个程序中,只会存在一份
- 由类名/接口名直接调用
- 修饰变量: 在整个程序中,只会存在一份
- 修饰方法: 方法可以被类名以及接口名直接调用
- final : 最终的 不可变
- 修饰变量: 表示这个变量初始化赋值之后,不可以再赋值了
- 修饰方法: 表示这个方法不可以被子类重写
- 修饰类: 表示这个类不可以被继承
```java
package com.zyf0724;
public class Door{
static int X;
int Y;
static void test(){
System.out.println ("静态方法!!");
}
// 代码块:对象创建时的初始化工作
{// 在创建对象时直接调用
System.out.println ("代码块!");
}
static {// 类被使用时直接调用,只会执行一次
System.out.println ("静态代码块!");
}
/**
* 行为固定了 不太方便扩展
*/
public void open(){
System.out.println("拔下门闩,开门!");
}
public void close(){
System.out.println("插上门闩,关门!");
}
}
class Manage{
public static void main(String[] args){
Door door = new Door();
door.open();
door.close();
// 测试静态关键字:
Door door1 = new Door();
Door door2 = new Door();
Door door3 = new Door();
door1.X=100;
door2.X=200;
Door.X=400;
door3.X=300;
door1.Y=100;
door2.Y=200;
door3.Y=300;
System.out.println (door1.X+" "+door1.Y);
System.out.println (door2.X+" "+door2.Y);
System.out.println (door3.X+" "+door3.Y);
System.out.println (Door.X);
Door.test();
}
}
```
- 方法: 默认由 abstract 修饰
- 1: 没有方法体,直接以;结尾
- 2:可以有返回值类型以及参数设定
- 3:不能写成私有的
```java
package com.zyf0724;
/**
* 类是以属性以及固定行为作为分类标准
* 动物: 吃
* 植物:
* 食人花
# 面向对象:
- 对象: Object
## 类与对象:
- 对象: Object 具体的事物
- 具体的某个人
- 类: class 类别的概念 人类
- 怎样才可以看作同样的类
- 具有相同、相似的属性特征/行为方式/功能
## 代码中:
- 类的定义:
- 关键字: class
- 格式: class 类名{ }
- 为什么要用代码写类?
- 就是用代码来描述一类事物的特征和行为
- 作为模板在计算机中生成具体的数据对象
- 类中应该写什么?
- 属性:一个词可以表达清楚
- 方法:动词 需要逻辑/运算来表达清楚 一段代码来描述
- 代码是什么? 媒介
- 代码是与机器沟通的指令
## 创建对象:
- 关键字: new
- 格式: 类名 对象名 = new 类名();
- 对象名: 复用
- 调用属性来赋值
- 调用方法来执行
## 基本数据类型:
- 单位: bit 0/1 二进制位
- 整数型:byte short int long | 8 16 32 64
- 浮点型:float double | 32 64
- 字符型:char | 16
- 布尔型:boolean | true/false
```java
package com06.zyf0626;
// 用户类
// 属性: 用户名 用户密码 用户地址 用户积分 手机号 ....
// 方法: 登录 修改密码 验证密码 个人信息
public class User{
/**
* 属性: 变量
* 属性数据类型 属性名;
*/
String user_name;
String user_pwd;
int age;
String user_adr;
String user_phone;
int socre;
// int 表达的数字范围
// 方法/函数
// void 函数名(参数列表){ }
void showUserInfo(){
System.out.println ("用户名:"+user_name);
System.out.println ("密码:"+user_pwd);
System.out.println ("年龄:"+age);
System.out.println ("用户地址:"+user_adr);
System.out.println ("手机号码:"+user_phone);
}
// 程序入口 必须写在类里面
public static void main(String[] args){
// 创建对象 对象名是user1
User user1 = new User();
// 对象名调用属性赋值
user1.user_name="张三";
user1.user_pwd="zs123";
user1.user_phone="18976762323";
user1.user_adr="深圳南山区";
user1.socre=600;
// 属性赋值 值是赋给user1
user1.showUserInfo ();
for(int i = 0; i
< 500; i++){
// 每个对象都是独立的
User user2 = new User ();
user2.user_name="游客"+i;
user2.showUserInfo ();
}
}
}
```
## 界面开发:
- 界面开发包:
- java.awt
- javax.swing
```java
package com.ui.zyf0713;
import javax.swing.JFrame;
import java.awt.*;
public class MyUI {
public void initUI(){
JFrame frame = new JFrame ("界面开发");
// 设置属性 : 尺寸-400*300 关闭操作-退出 可视化-true
frame.setSize (800, 600);
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE);
frame.setVisible (true);
for (int i = 0; i < 1000;i++) {
System.out.println ("A");
}
// 程序的执行需要时间
// 获取Graphics
Graphics g = frame.getGraphics ();
g.drawLine (100,100,500,100);
// 监听实现
UIListen uil = new UIListen();
frame.addMouseListener(uil);
uil.setGraphics (g);
}
public static void main(String[] args){
MyUI myui = new MyUI();
myui.initUI();
// MyUI myui1 = new MyUI();
// myui1.initUI();
}
}
```
## 所有的可视化组件都有一个绘制的方法
public void paint(Graphics g){
}
- Graphics 图形 GPU - 显卡
- 实现绘制
- Graphics 与可视化组件 容器深度绑定的
- 窗体对象/按钮对象 都有一个自己的Graphics 对象
- 获取这个对象的方式:
- 可视化之后 Graphics g = frame.getGraphics();
- 继承这个组件类/窗体类, 重写paint方法
- paint方法自带一个Graphics 参数
## 鼠标监听器:
MouseListener
- 用法:
- 1: 创建一个新的类 使用 implements 实现鼠标监听器
```java
import java.awt.event.MouseListener;
public class UIListen implements MouseListener{
}
```
- 2: 实现重写MouseListener中的所有方法
```java
import java.awt.event.MouseListener;
public class UIListen implements MouseListener{
@Override
public void mouseClicked(MouseEvent e){
}
@Override
public void mousePressed(MouseEvent e){
}
@Override
public void mouseReleased(MouseEvent e){
}
@Override
public void mouseEntered(MouseEvent e){
}
@Override
public void mouseExited(MouseEvent e){
}
}
```
- 3: 将写好的监听类 添加到需要监听器组件/窗体上
- UIListen uil = new UIListen();
// 窗体添加监听
addMouseListener(uil);
- 没有继承的就拿frame调用
- UIListen uil = new UIListen();
- frame.addMouseListener(uil);
- 4: 画棋子
- 1:在监听中创建一个Grap
that's all ,thinks for watching