12.运算符重载

12.面向对象-封装-运算符重载


12.1 知识点

运算符重载的基本概念

概念:让自定义类和结构体能够使用运算符

使用关键字: operator

特点:

  • 一定是一个公共的静态方法
  • 返回值写在 operator
  • 逻辑处理自定义

作用:让自定义类和结构体对象可以进行运算

注意:

  • 条件运算符需要成对实现
  • 一个符号可以多个重载
  • 不能使用 refout

运算符重载的基本语法

public static 返回类型 operator 运算符(参数列表)

运算符重载的实例

class 语句块外 namespace 语句块内

// 点类
class Point
{
    // x y 坐标
    public int x;
    public int y;

    // 重载加法 两个点相加
    public static Point operator +(Point p1, Point p2)
    {
        Point p = new Point();
        p.x = p1.x + p2.x;
        p.y = p1.y + p2.y;
        return p;
    }

    // 重载加法 点和值相加
    public static Point operator +(Point p1, int value)
    {
        Point p = new Point();
        p.x = p1.x + value;
        p.y = p1.y + value;
        return p;
    }

    // 重载加法 值和点相加 参数顺序不一样 会影响重载的使用
    public static Point operator +(int value, Point p1)
    {
        Point p = new Point();
        p.x = p1.x + value;
        p.y = p1.y + value;
        return p;
    }
}

运算符重载的使用

主函数内

Point p1 = new Point();
p1.x = 1;
p1.y = 1;

Point p2 = new Point();
p2.x = 2;
p2.y = 2;

// 重载加法 两个点相加
Point p3 = p1 + p2; // p3(3,3)

// 重载了加法 点和值相加
// public static Point operator +(Point p1, int value)
Point p4 = p3 + 1; // p4(4,4)

// 重载加法 值和点相加 参数顺序不一样 会影响运算符重载的使用
// public static Point operator +(int value, Point p1)
// 必须有这个运算符重载 p5 才不会报错
Point p5 = 1 + p4; // p5(5,5)

可重载和不可重载的运算符

可重载的运算符

  • 算数运算符: +, -, *, /, %, ++, --
  • 逻辑运算符: !
  • 位运算符: |, &, ^, <<, >>, ~
  • 条件运算符: >, <, >=, <=, ==, !=, true, false

不可重载的运算符

  • 逻辑与(&&)、逻辑或(||)
  • 索引符 []
  • 强转运算符 ()
  • 特殊运算符,如点.、三目运算符? :、赋值符号=

总结

  • 关键词: operator
  • 固定语法:public static 返回值 operator 运算符(参数列表)
  • 作用:让自己定义类或结构体对象进行运算
  • 注意:
    • 参数的数量
    • 条件运算符的配对实现
    • 一个符号可以多个重载
    • 不能用 refout

12.2 知识点代码

using System;

namespace Lesson10_封装_运算符重载
{
    #region 知识点一 运算符重载的基本概念
    //概念
    //让自定义类和结构体 能够使用运算符

    //使用关键字:operator

    //特点
    //1.一定是一个公共的静态方法
    //2.返回值写在operator前
    //3.逻辑处理自定义

    //作用
    //让自定义类和结构体对象可以进行运算
    //注意
    //1.条件运算符需要成对实现
    //2.一个符号可以多个重载
    //3.不能使用ref和out
    #endregion

    #region 知识点二 运算符重载的基本语法
    //public static 返回类型 operator 运算符(参数列表)
    #endregion

    //class语句块外 namespace语句块内

    #region 知识点三  运算符重载的实例

    //点类
    class Point
    {
        //x y 坐标
        public int x;
        public int y;

        //重载加法 两个点相加
        public static Point operator +(Point p1, Point p2)
        {
            Point p = new Point();
            p.x = p1.x + p2.x;
            p.y = p1.y + p2.y;
            return p;
        }

        //报错 二元运算符的参数之一必须是包含类型
        //public static Point operator +(int p1, int p2)
        //{
        //    Point p = new Point();
        //    return p;
        //}

        //重载加法 点和值相加
        public static Point operator +(Point p1, int value)
        {
            Point p = new Point();
            p.x = p1.x + value;
            p.y = p1.y + value;
            return p;
        }

        //重载加法 值和点相加 参数顺序不一样 会影响重载的使用
        public static Point operator +(int value, Point p1)
        {
            Point p = new Point();
            p.x = p1.x + value;
            p.y = p1.y + value;
            return p;
        }

        //报错 二元运算符的定义必须有两个参数。
        //public static Point operator +(Point p1, Point p2,Point p3)
        //{
        //    Point p = new Point();
        //    return p;
        //}


        #region 知识点五 可重载和不可重载的运算符

        #region 可重载的运算符

        #region 算数运算符

        //注意 符号需要两个参数还是一个参数
        //两个参数 - * / %
        //一个参数 ++ --

        public static Point operator -(Point p1, Point P2)
        {
            return null;
        }
        public static Point operator *(Point p1, Point P2)
        {
            return null;
        }
        public static Point operator /(Point p1, Point P2)
        {
            return null;
        }
        public static Point operator %(Point p1, Point P2)
        {
            return null;
        }

        public static Point operator ++(Point p1)
        {
            return null;
        }
        public static Point operator --(Point p1)
        {
            return null;
        }
        #endregion

        #region 逻辑运算符

        //注意 符号需要两个参数还是一个参数
        //逻辑运算符只有 ! 可重载
        public static bool operator !(Point p1)
        {
            return false;
        }

        #endregion

        #region 位运算符

        //注意 符号需要两个参数还是一个参数
        //两个参数 | & ^ << >>
        //一个参数 ~ 
        public static Point operator |(Point p1, Point p2)
        {
            return null;
        }
        public static Point operator &(Point p1, Point p2)
        {
            return null;
        }
        public static Point operator ^(Point p1, Point p2)
        {
            return null;
        }
        public static Point operator <<(Point p1, int num)
        {
            return null;
        }
        public static Point operator >>(Point p1, int num)
        {
            return null;
        }
        public static Point operator ~(Point p1)
        {
            return null;
        }

        #endregion

        #region 条件运算符
        //1.返回值一般是bool值 也可以是其它的
        //2.相关符号必须配对实现

        //假如重载了大于 没有重载小于 会报错 其他同理
        //运算符“operator”还需要定义一个匹配的运算符“missing_operator”
        //用户定义的==运算符需要用户定义的!=运算符,反之亦然。
        //这同样适用于用户定义的真运算符和用户定义的假运算符。

        //两个参数 > < >= <= == !=
        //一个参数 true false

        public static bool operator >(Point p1, Point p2)
        {
            return false;
        }

        public static bool operator <(Point p1, Point p2)
        {
            return false;
        }

        public static bool operator >=(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator <=(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator ==(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator !=(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator true(Point p1)
        {
            return false;
        }
        public static bool operator false(Point p1)
        {
            return false;
        }
        #endregion

        #endregion

        #region 不可重载的运算符

        //逻辑与(&&) 逻辑或(||)
        //索引符 []
        //强转运算符 ()
        //特殊运算符 
        //点.   三目运算符? :  赋值符号=

        #endregion

        #endregion
    }
    #endregion




    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("运算符重载");

            //主函数

            #region 知识点四  运算符重载的使用

            Point p1 = new Point();
            p1.x = 1;
            p1.y = 1;

            Point p2 = new Point();
            p2.x = 2;
            p2.y = 2;

            //重载加法 两个点相加
            Point p3 = p1 + p2;//p3(3,3)

            //重载了加法 点和值相加
            //public static Point operator +(Point p1, int value)
            Point p4 = p3 + 1;//p4(4,4)

            //重载加法 值和点相加 参数顺序不一样 会影响运算符重载的使用
            //public static Point operator +(int value, Point p1)
            //必须有这个运算符重载 p5才不会报错
            Point p5 = 1 + p4;//p5(5,5)


            #endregion
        }
    }

    //总结

    //关键词:operator
    //固定语法:public static 返回值 operator 运算符(参数列表)
    //作用:让自己定义类或结构体对象 进行运算
    //注意:
    //1.参数的数量
    //2.条件运算符的配对实现
    //3.一个符号可以多个重载
    //4.不能用ref和out
}

12.3 练习题

定义一个位置结构体,重载判断是否相等的运算符

(x1,y1) == (x2,y2) => 两个值同时相等才为true

class语句块外 namespace语句块内

//位置结构体 运算符重载也可以用到结构体中 和类一模一样
struct Position
{
    public int x;
    public int y;

    //重载了==
    public static bool operator ==(Position p1, Position p2)
    {
        return p1.x == p2.x && p1.y == p2.y;
    }

    //因为重载了== 所以必须要重载!=
    public static bool operator !=(Position p1, Position p2)
    {
        return !(p1 == p2);
    }
}

主函数内

// 主函数内
Position p1;
p1.x = 1;
p1.y = 1;

Position p2;
p2.x = 2;
p2.y = 1;

Position p3;
p3.x = 1;
p3.y = 1;

if (p1 != p2)
{
    Console.WriteLine("p1和p2不相等");//p1和p2不相等
}

if (p1 == p3)
{
    Console.WriteLine("p1和p3相等");//p1和p3相等
}

定义一个Vector3类,通过重载运算符实现运算

(x1,y1,z1) + (x2,y2,z2) = (x1+x2,y1+y2,z1+z2)
(x1,y1,z1) - (x2,y2,z2) = (x1-x2,y1-y2,z1-z2)
(x1,y1,z1) * num = (x1num,y1num,z1*num)

class语句块外 namespace语句块内

//三维向量类
class Vector3
{
    public int x;
    public int y;
    public int z;

    public Vector3(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public static Vector3 operator +(Vector3 v1, Vector3 v2)
    {
        return new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
    }

    public static Vector3 operator -(Vector3 v1, Vector3 v2)
    {
        return new Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }

    public static Vector3 operator *(Vector3 v1, int num)
    {
        return new Vector3(v1.x * num, v1.y * num, v1.z * num);
    }
}

主函数内

// 主函数内
Vector3 v1 = new Vector3(1, 1, 1);
Vector3 v2 = new Vector3(2, 2, 2);

Vector3 v3 = v1 - v2;
Console.WriteLine("v3 = v1 - v2,v3的坐标是:{0}|{1}|{2}", v3.x, v3.y, v3.z);
//v3 = v1 - v2,v3的坐标是:-1|-1|-1

v3 = v3 * 10;
//v3 *= 10;//这样写也行
Console.WriteLine("v3 *= 10,v3的坐标是:{0}|{1}|{2}", v3.x, v3.y, v3.z);
//v3 *= 10,v3的坐标是:-10|-10|-10

12.4 练习题代码

using System;

namespace Lesson10_练习题
{
    //class语句块外 namespace语句块内

    #region 练习题一
    //定义一个位置结构体或类,为其重载判断是否相等的运算符
    //(x1, y1) == (x2, y2)   =>  两个值同时相等才为true

    //位置结构体 运算符重载也可以用到结构体中 和类一模一样
    struct Position
    {
        public int x;
        public int y;

        //重载了==
        public static bool operator ==(Position p1, Position p2)
        {
            if (p1.x == p2.x && p1.y == p2.y)
            {
                return true;
            }
            return false;
        }

        //因为重载了== 所以必须要重载!=
        public static bool operator !=(Position p1, Position p2)
        {
            if (p1.x == p2.x && p1.y == p2.y)
            {
                return false;
            }
            return true;
        }
    }

    #endregion

    #region 练习题二
    //定义一个Vector3类(x,y,z)通过重载运算符实现以下运算
    //(x1, y1, z1) + (x2, y2, z2) = (x1+x2,y1+y2,z1+z2)
    //(x1, y1, z1) - (x2, y2, z2) = (x1-x2,y1-y2,z1-z2)
    //(x1, y1, z1) * num = (x1 * num, y1 * num, z1 * num)

    //三维向量类
    class Vector3
    {
        public int x;
        public int y;
        public int z;
        public Vector3(int x, int y, int z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public static Vector3 operator +(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
        }
        public static Vector3 operator -(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
        }

        public static Vector3 operator *(Vector3 v1, int num)
        {
            return new Vector3(v1.x * num, v1.y * num, v1.z * num);
        }
    }
    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("运算符重载练习题");

            //主函数内

            #region 练习题一

            Position p1;
            p1.x = 1;
            p1.y = 1;

            Position p2;
            p2.x = 2;
            p2.y = 1;

            Position p3;
            p3.x = 1;
            p3.y = 1;

            if (p1 != p2)
            {
                Console.WriteLine("p1和p2不相等");//p1和p2不相等
            }

            if (p1 == p3)
            {
                Console.WriteLine("p1和p3相等");//p1和p3相等
            }

            #endregion

            #region 练习题二

            Vector3 v1 = new Vector3(1, 1, 1);
            Vector3 v2 = new Vector3(2, 2, 2);

            Vector3 v3 = v1 - v2;
            Console.WriteLine("v3 = v1 - v2,v3的坐标是:{0}|{1}|{2}", v3.x, v3.y, v3.z);
            //v3 = v1 - v2,v3的坐标是:-1|-1|-1

            v3 = v3 * 10;
            //v3 *= 10;//这样写也行
            Console.WriteLine("v3 *= 10,v3的坐标是:{0}|{1}|{2}", v3.x, v3.y, v3.z);
            //v3 *= 10,v3的坐标是:-10|-10|-10

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏